Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

522 Advanced I/O Chapter 14


Example


In Section 20.8, in the function _db_writeidx, we need to write two buffers
consecutively to a file. The second buffer to output is an argument passed by the caller,
and the first buffer is one we create, containing the length of the second buffer and a file
offset of other information in the file. Thereare three ways we can do this.


  1. Callwritetwice, once for each buffer.

  2. Allocateabuffer of our own that is large enough to contain both buffers, and
    copy both into the new buffer.Wethen callwriteonce for this new buffer.

  3. Callwritevto output both buffers.
    The solution we use in Section 20.8 is to usewritev,but it’s instructive to compare it to
    the other two solutions.
    Figure14.23 shows the results from the three methods just described.


Linux(Intel x86) Mac OS X(Intel x86)
User System Clock User System Clock
Operation

twowrites0.06 2.04 2.13 0.85 8.33 13.83
buffer copy,then onewrite 0.03 1.13 1.16 0.70 4.87 9.25
onewritev 0.04 1.21 1.26 0.43 5.34 9.24

Figure 14.23Timing results comparingwritevand other techniques

The test program that we measured output a 100-byte header followed by 200 bytes of
data. This was done 1,048,576 times, generating a 300-megabyte file. The test program
has three separate cases—one for each of the techniques measured in Figure14.23. We
usedtimes(Section 8.17) to obtain the user CPU time, system CPU time, and wall
clock time beforeand after the writes. All three times areshown in seconds.
As we expect, the system time increases when we callwritetwice, compared to
calling eitherwriteorwritevonce. This correlates with the results in Figure3.6.
Next, note that the sum of the CPU times (user plus system) is slightly less when we
do a buffer copy followed by a singlewritecompared to a single call towritev.With
the singlewrite, we copy the buffers to a staging buffer at user level, and then the
kernel will copy the data to its internal buffers when we callwrite.Withwritev,we
should do less copying, because the kernel only needs to copy the data directly into its
staging buffers. The fixed cost of usingwritevfor such small amounts of data,
however, is greater than the benefit. As the amount of data we need to copy increases,
the moreexpensive it will be to copy the buffers in our program, and thewritev
alternative will be moreattractive.
Don’t infer too much about the relative performance of Linux and Mac OS X from the numbers
shown in Figure14.23. The two computers werevery different: they had different processor
generations, different amounts of RAM, and disks with different speeds.To do an apples-to-
apples comparison of one operating system to another,weneed to use the same hardwarefor
each operating system.
Free download pdf