Trivial Disk Speed Testing
Often I want to run simple read and write tests of a disk for sanity testing. Performance geeks will object to simple tests as being meaningless, but these are often good enough for quick comparison testing.
Some might object to using /dev/urandom because computing random numbers can be expensive. I'm assuming the urandom device generates Pseudo Random Numbers without much load on the system; I assume the speed it can generate those numbers is consistent (no strange pauses and latency); and I assume it can supply this data faster than most storage systems.
Check your block size (even though it's always 512 Bytes)
# dd if=/dev/urandom of=TESTDATA count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.000458444 s, 1.1 MB/s
Create a 1MB test data file (random bytes)
Oh, look! Now we're almost testing speed, since `dd` reports its own statistics.
dd if=/dev/urandom of=TESTDATA count=2048 2048+0 records in 2048+0 records out 1048576 bytes (1.0 MB) copied, 0.309145 s, 3.4 MB/s
This does the same, but will make the math easier in future tests. This sets the blocksize to 1MB and count to 1 block. It is good to see that `dd` doesn't show any odd behavior here. The speed is about the same.
# dd if=/dev/urandom of=TESTDATA bs=1048576 count=1 1+0 records in 1+0 records out 1048576 bytes (1.0 MB) copied, 0.296067 s, 3.5 MB/s
Now create a 10 MB file. Setting the blocksize make it more clear how big a file we want.
It's debatable whether one should use 'fsync' or 'fdatasync' options. The 'fsync' option also makes sure filesystem metadata is written to disk. That makes more sense if you are testing the whole filesystem speed. The 'fdatasync' option only ensure the file's contents is on the disk. That would be better if you care about testing raw disk performance... But this is all theoretical. In general you won't see a difference and these are primitive tests that you wouldn't want to take to a performance testing debate.
This shows why primitive testing can be bad. You have to know what you are doing. Look at these terrible results. It turns out that `dd` reads one byte then writes one byte over and over until done.
# dd if=/dev/urandom of=TESTDATA bs=1 count=1048576 1048576+0 records in 1048576+0 records out 1048576 bytes (1.0 MB) copied, 6.32568 s, 166 kB/s
Things get even worse if you add the 'sync' option because now `dd` will read then write then sync the disk. Ouch. Super slow. It seems that disks are not designed to write one byte at a time and guarantee that the byte was actually written to the disk before going on to the next byte. This is only 1K of data! But it is nice to see that the sync and blocksize options actually do seem to do what say they will -- tune performance.
# dd if=/dev/urandom of=TESTDATA oflag=sync bs=1 count=1024 1024+0 records in 1024+0 records out 1024 bytes (1.0 kB) copied, 1.42996 s, 0.7 kB/s
Streaming big bursts or lots of little discrete chunks
So now we see that performance measurement depends on how we want to use the disk. Do we only care how fast we can write a giant blob of data? Or do we care how fast it can write lots of little blocks of data. If you are recording video then you probably care more about writing giants blobs of data. If you are writing small transactions in a log file (such as a server log) then you probably care more about small block performance.
If you really are just trying to test the raw disk write speed then you should just test a large burst. It really is the operating system's job to worry about how to manage lots of small requests and still get performance.
read speed testing
When using `dd` for read testing don't forget the "iflag=direct" option. All files in Linux pass through the Page Cache, so successive testing of read performance on file will represent the speed to read from cache, not disk. That is usually not what people want, but it has it's place.
dd if=TESTDATA iflag=direct of=/dev/null