POSIX Asynchronous I/O

Used judiciously, asynchronous I/O (AIO) can provide a significant speed benefit, says David Chisnall. Perhaps enough to help your program overcome the fact that modern processors can really zoom, while hard drives still drag.

To download the source code to the examples in this
article, click here.

Like this article? We recommend

Since I first learned to program, a lot has changed in the way computers
work. While this fact isn’t always apparent to the user, it means that
optimizations I was taught now result in highly suboptimal code. One thing,
however, has remained constant: Hard drives are slow.

In recent years, this situation has gotten worse rather than better. CPU
speeds have grown faster exponentially, while hard drives have barely managed
even a linear speed increase. DMA transfers, becoming common, have widened the
gap even more; now CPUs don’t have to do nearly as much work when handling
disk I/O.

With the traditional UNIX I/O mechanisms, you issue a read or write system
call, and then wait until the call has completed. A typical hard drive takes
about 9 ms to position the head and then a little longer to perform the
operation—and that’s assuming a linear. A modern CPU runs at least 1
GHz. In the time it takes to position the disk head, a 1 GHz CPU runs for nine
million clock cycles. You can get a lot done in that many cycles.

The obvious solution is to dispatch the read or write requests as soon as you
know what data you’re going to need, and then do something else while the
OS processes the request. The asynchronous I/O (AIO) APIs, provided as part of
the POSIX real-time extensions, allow you to do exactly that.

Operating System Support

Commercial UNIX systems have supported POSIX asynchronous I/O. Some of the best documentation currently available comes from IRIX and HP/UX. More recently, Free UNIX variants have started to support it; Linux and FreeBSD both support most of the specification, for example.

Support is slightly different between operating systems. Code using AIO on some platforms, including Linux and Solaris, must be linked with -lrt to provide support for the POSIX real-time extensions. On FreeBSD, AIO support isn’t built into the default kernel and must be loaded as a module with the following command:

# kldload aio

On versions of Mac OS X prior to 10.3, AIO wasn’t supported at all, and until OS X 10.4 AIO operations were supported only on files, not other file descriptor types such as sockets. Using AIO can give significant performance benefits, but it can also increase the testing overhead when porting to new platforms.