29

Assuming there is some bit of code that reads files for multiple consumers, and the files are of any arbitrary size: At what size does it become more efficient to read the file asynchronously? Or to put it another way, how small must a file be for it to be faster just to read it synchronously?

I've noticed (and perhaps I'm incorrect) that when reading very small files, it takes longer to read them asynchronously than synchronously (in particular with .NET). I'm assuming this has to do with set up time for things like I/O Completion Ports, threads, etc.

Is there any rule of thumb to help out here? Or is it dependent on the system and the environment?

3
  • Can you give the code that you use for benchmark? I think that this could happen only in the case where the file size is smaller than the internal buffer size of the stream reader. But if you have to read that many small files you will probably hit other problems with disk i/o Commented Sep 12, 2012 at 14:33
  • I don't have the code handy, I'm afraid. It's something I ran into a while back and it's been on my mind since then. The code was in .NET and was essentially a straight File.ReadAllBytes() vs FileStream.BeginRead() in a for loop
    – blesh
    Commented Sep 12, 2012 at 15:16
  • When the curves that represent their efficiency cross, and async IO exits the crossing at a higher value than the sync IO curve. Commented Sep 12, 2012 at 17:23

5 Answers 5

15

Unfortunately, the answer is, "it depends." It would be easy for you to write a small program to empirically determine the times of both async and sync reads.

It will depend on lots of factors. Are they stored on spinning disks, SSD, or a network drive? What kind of CPU are you using? How many sockets/cores? Are you running in an VM or bare metal? Are you running an ancient OS or modern one?

1
  • 1
    Yeah, I figured as much. I guess I was hoping there was some sort of study to use as a guide or rule of thumb.
    – blesh
    Commented Sep 12, 2012 at 15:12
10

Async has 3 main advantages:

  1. It lowers CPU utilization. This could be useful if you are also doing CPU-heavy operations with data you just read.
  2. Using some kind of async infrastructure makes the code easy to paralelise. Especially if you are reading lots of files.
  3. By sending multiple read-write requests to OS, OS and HW can re-order those operations to be completed faster. SATA2 has such feature.

I believe main advantage of asynchronous read is when you are working with lots of files or you need lots of CPU power.

2
  • Note for the point 2 that it will not optimize anything if the I/O operation is the bottleneck. Things are different if you're accessing in parallel, through RAID or network, files which are located on different disks. Commented Sep 12, 2012 at 16:45
  • 7
    Hmm, I'm having trouble understanding what you mean with #1. I'd say it's the other way around in practice. Because with the async case, you are now changing your thread(s) from blocked waiting for I/O (0% CPU) to continue normal processing (>0% CPU).
    – Isak Savo
    Commented Sep 19, 2012 at 6:13
3

It depends

One thing to keep in mind is how expensive is a context switch between processes. Node.JS is designed the way it is because it assumes that doing a context switch is very expensive and you will otherwise have a lot of processes waiting on IE which will bog down the computer.

On the other hand Erlang makes a process context switch very cheap so everything can be synchronous and the Erlang run time can keep track of the whole thing.

So the factors to consider:

  • the Cost of a context switch operation
  • the speed of the disk for seek operations
  • the speed of the disk for read operations
  • are the files in cache

And I am sure I am leaving out a half a dozen factors

2

I'm not sure there's a particular "point", but it makes the most sense when you've got a lot of threads working, as it allows you to overlap your I/O with other work. If you've got spare threads going idle, then reading asynchronously isn't going to give you any advantage. It's only when you've got work queues filling up and your thread could be usefully doing other work instead of waiting for I/O that async file access gives any advantage.

1
  • yep, that's the whole point of multithreading!
    – Vlad
    Commented Sep 18, 2012 at 20:27
1

I think the problem here is not so much read speeds, as it's the latency.

If you're reading from a network drive, or from a slow mechanical hard disk drive with long queues, the performance will take a nosedive for reading. And if your app is also doing the reading in GUI thread, in which case it's a very bad application, then it will be awful for the user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.