You're right that you will not get the benefit of this by default, because a blocking read stops your thread from doing any processing. Hans is right that modern OSes already take care of all the little details of DMA and interrupt completion routines.
You need to use the architecture you've described, of issuing a request in advance of when you will use the data. Issue asynchronous I/O requests (on Windows these are called OVERLAPPED
). Then the flow will go exactly as you envisions, but the DMA and interrupts are handled in the drivers.
On Windows, take a look at FILE_FLAG_OVERLAPPED
(to CreateFile
) and ReadFile
(if you like events) or ReadFileEx
(if you like callbacks). If you don't have to process the data in any particular order, then add a completion port to the mix, which queues the completion responses.
On Linux, OSX, and many other Unix-like OSes, look at aio_read
. Or fadvise
. Or use mmap
with madvise
.
And you can get these benefits without even writing native code. .NET recently added the ReadAsync
method to its FileStream
, which can be used with continuation-passing style in the form of Task
objects, with async
/await
syntactic sugar in the C# compiler.