-- Warning, this is in early development stage --
This code attempts reading a random block from the block device of your
choice and tells you about the time it spends waiting for that IO operation
to complete. Bear in mind that measuring this from userpace means that you are
accounting for the scheduler, the ioscheduler, and other delays introduced
by the kernel.
Currently it uses O_DIRECT to avoid caching of blocks by the kernel, so
with kernels <2.6 (such as 2.4) reading will fail. You can try on
those without O_DIRECT, but then your blocks will be cached, which
shouldn't be a big problem because we are reading random blocks, and the
probability of reading a cached block will be low, depending on the size of
the device.
By now, it doesn't write, so *should* be safe with your data. Of course, this is without warranty of any kind, and all that. So I take no responsibility on any damage this code does.
nebula:/home/piotr/iolat# ./iolat /dev/sda AVG: 0.0 ms Last read took: 11.8 ms Runtime: 1 s AVG: 1.2 ms Last read took: 13.1 ms Runtime: 2 s AVG: 2.4 ms Last read took: 9.7 ms Runtime: 3 s AVG: 3.1 ms Last read took: 8.8 ms Runtime: 4 s AVG: 3.7 ms Last read took: 4.3 ms Runtime: 5 s AVG: 3.7 ms Last read took: 8.0 ms Runtime: 6 s AVG: 4.2 ms Last read took: 4.4 ms Runtime: 7 s AVG: 4.2 ms Last read took: 7.9 ms Runtime: 8 s AVG: 4.6 ms Last read took: 4.0 ms Runtime: 9 s AVG: 4.5 ms Last read took: 8.1 ms Runtime: 10 s AVG: 4.9 ms Last read took: 10.2 ms Runtime: 11 s AVG: 5.4 ms Last read took: 10.2 ms Runtime: 12 s AVG: 5.9 ms Last read took: 10.9 ms Runtime: 13 s AVG: 6.4 ms Last read took: 10.0 ms Runtime: 14 s AVG: 6.7 ms Last read took: 10.9 ms Runtime: 15 s AVG: 7.1 ms Last read took: 11.5 ms Runtime: 16 s AVG: 7.6 ms Last read took: 9.0 ms Runtime: 17 s
Nice but inefficient plotting:
./iolat-plot.pl /dev/hdaWill produce something like:

here.
Delays caused by loading the disk, several cp -R for example:
here.