Thursday, May 01, 2014

Linux - How to Check Hard Disk Transfer Speed

You can use "hdparm" to check/test hard disk speed. hdparm provides a command line interface to various kernel interfaces supported by the Linux SATA/PATA/SAS "libata" subsystem and the older IDE driver subsystem. Many newer USB drive enclosures now also support "SAT" (SCSI-ATA Command Translation) and therefore may also work with hdparm.

Hard Disk Transfer Speed:
# use df command or fdisk command to get a list of drives
# for example, /dev/sdb
# then run "hdparm -tT"

To find out SATA hard disk spped:
# hdparm -I /dev/sda | grep -i speed
 * Gen1 signaling speed (1.5Gb/s)
 * Gen2 signaling speed (3.0Gb/s)

This indicates that my hard disk can use both 1.5Gb/s or 3.0Gb/s speed. But in order to use 3.0Gb/s, your motherboard must have support for SATA-II. This is not the actual speed that your hard disk is capable of.

# hdparm -tT /dev/sdb
/dev/sdb:
 Timing cached reads:   9214 MB in  2.00 seconds = 4610.08 MB/sec
 Timing buffered disk reads:  254 MB in  3.02 seconds =  84.15 MB/sec

-T: Perform timings of cache reads for benchmark and comparison purposes
-t: Perform  timings of device reads for benchmark and comparison purposes

For meaningful results, this operation should be repeated 2-3 times on an otherwise inactive system (no other active process) with at least a couple of megabytes of free memory. "-T" displays the speed of reading directly from the Linux buffer cache without disk access. "-T" measurement is essentially an indication of the throughput of the processor, cache, and memory of the system under test. "-t" displays the speed of reading through the buffer cache to the disk without any prior caching of data. "-t" measurement is an indication of how fast the drive can sustain sequential data reads under Linux, without any filesystem overhead. To ensure accurate measurements, the buffer cache is flushed during the processing of -t using the BLKFLSBUF ioctl.

Here is a bash command to do tests 3 times:
# for i in 1 2 3; do hdparm -tT /dev/sdb; done

As both "-t" and "-T" are for read testing, we can use "dd" command to test the write speed.

Hard disk writing speed:
"dd" stands for "data definition/description", or it is often jokingly said to stand for "destroy data".

"dd" will give you information on write speed by copying data at the low level (device files are often access directly). Since it does low level writings, you should use "dd" command carefully. If "dd" is used incorrectly, data loss will be the result.

Cache:
Modern OS does not normally write files immediately to hard disks. Temp memory will be used to cache writes and reads. To prevent I/O performance measurements will not be affected by these caches, we use "oflag" parameter. Three flags are interesting here:

  • direct (use direct I/O for data)
  • dsync (use synchronized I/O for data)
  • sync (likewise, but also for metadata)

Idealy, data to be written should be read from /dev/zero and written to an hard disk (i.e /dev/sdb). But if you are testing a hard disk already contains data, you can create a normal file (i.e /tmp/test1GB). Note that if you create a file, the write performance will be a lettle slower (because metadata will also be written).

Note:
When using if=/dev/zero and bs=1G, Linux will need 1GB of free space in RAM. If your test system does not have sufficient RAM available, use a smaller parameter for bs (such as 512MB).
In order to get results closer to real-life, we recommend performing the tests described several times (three to ten times, for example).

Writing test:

Throughput:
We will write 1GB to a file, first with the cache activated:
# hdparm -W1 /dev/sdb
(-W: Get/set the IDE/SATA drive´s write-caching feature)
# hdparm -W1 /dev/sdb
/dev/sdb:
 setting drive write-caching to 1 (on)
 write-caching =  1 (on)

# dd if=/dev/zero of=/tmp/output1G bs=1G count=1 oflag=direct
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 13.8042 s, 77.8 MB/s

Then, with the cache deactivated:
# hdparm -W0 /dev/sdb
/dev/sdb:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

# dd if=/dev/zero of=/tmp/output1G bs=1G count=1 oflag=direct
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 38.9593 s, 27.6 MB/s

Latency:
We will write 512 bytes to disk for one thousand times, first with cache activated:
# hdparm -W1 /dev/sdb
/dev/sdb:
 setting drive write-caching to 1 (on)
 write-caching =  1 (on)

# dd if=/dev/zero of=/tmp/output1G bs=512 count=1000 oflag=direct
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 0.203692 s, 2.5 MB/s

Then, with cache deactivated
# hdparm -W0 /dev/sdb
/dev/sdb:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

# dd if=/dev/zero of=/tmp/output1G bs=512 count=1000 oflag=direct
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 24.8429 s, 20.6 kB/s

No comments: