hdparm is a tool that allows you to tweak various parameters of hard drives and optical drives. Depending on the drive, you can get very high results.
This is our base drive. I reset it back to no options for this demonstration. (Note all commands were run as root)
hdparm -d0 -c0 -m0 -u0 /dev/hdb /dev/hdb: setting 32-bit IO_support flag to 0 setting multcount to 0 setting unmaskirq to 0 (off) setting using_dma to 0 (off) multcount = 0 (off) IO_support = 0 (default 16-bit) unmaskirq = 0 (off) using_dma = 0 (off)
Now to get the timings for the drive. This is done with hdparm's -Tt options. In order for a decent timing, I ran them 5 times in a row
for i in $(seq 1 1 5);do;hdparm -Tt /dev/hdb; done /dev/hdb: Timing cached reads: 464 MB in 2.00 seconds = 232.00 MB/sec Timing buffered disk reads: 10 MB in 3.77 seconds = 2.65 MB/sec /dev/hdb: Timing cached reads: 440 MB in 2.01 seconds = 219.32 MB/sec Timing buffered disk reads: 10 MB in 3.73 seconds = 2.68 MB/sec /dev/hdb: Timing cached reads: 440 MB in 2.01 seconds = 219.33 MB/sec Timing buffered disk reads: 10 MB in 3.63 seconds = 2.76 MB/sec /dev/hdb: Timing cached reads: 434 MB in 2.01 seconds = 216.27 MB/sec Timing buffered disk reads: 8 MB in 3.10 seconds = 2.58 MB/sec /dev/hdb: Timing cached reads: 448 MB in 2.00 seconds = 223.74 MB/sec Timing buffered disk reads: 10 MB in 3.76 seconds = 2.66 MB/sec
You can see there are variances in the timings, but on average we are getting around 220 MB/sec on cached reads and 2.60 MB/sec on buffered reads.
One option to tweak is the Multiple Sector I/O setting (aka IDE Block Mode). This allows the transfer of multiple sectors per I/O interrupt. You can find out what the max rated MultiSector I/O for the device is with hdparm -i DEVICE and looking at the MaxMultiSect field. Typically this will be around 16 for newer drives. You set it with the -m option
hdparm -u0 -d0 -c0 -m16 /dev/hdb /dev/hdb: setting 32-bit IO_support flag to 0 setting multcount to 16 setting unmaskirq to 0 (off) setting using_dma to 0 (off) multcount = 16 (on) IO_support = 0 (default 16-bit) unmaskirq = 0 (off) using_dma = 0 (off)
And we rerun the timings
for i in $(seq 1 1 5);do;hdparm -Tt /dev/hdb; done /dev/hdb: Timing cached reads: 462 MB in 2.00 seconds = 230.88 MB/sec Timing buffered disk reads: 8 MB in 3.09 seconds = 2.59 MB/sec /dev/hdb: Timing cached reads: 406 MB in 2.01 seconds = 202.23 MB/sec Timing buffered disk reads: 8 MB in 3.11 seconds = 2.57 MB/sec /dev/hdb: Timing cached reads: 440 MB in 2.00 seconds = 219.59 MB/sec Timing buffered disk reads: 8 MB in 3.24 seconds = 2.47 MB/sec /dev/hdb: Timing cached reads: 460 MB in 2.01 seconds = 229.34 MB/sec Timing buffered disk reads: 8 MB in 3.70 seconds = 2.16 MB/sec /dev/hdb: Timing cached reads: 464 MB in 2.01 seconds = 231.01 MB/sec Timing buffered disk reads: 8 MB in 3.27 seconds = 2.45 MB/sec
Not much if any increase. Interestingly enough, according to the hdparm manpage, Western Digital drives seem to perform better with MultiSector options of 4 or 8. This is a WD drive, but I didn't investigate the other settings. It should be noted that the impact on my system decreased though
This is an interesting option that doesn't actually give a speed boost to the drive itself, but rather improves overall system performance. Turning this on allows the driver to unmask other interrupts while processing a disk interrupt. It is handled with the -u option
hdparm -u1 -c0 -d0 -m16 /dev/hdb /dev/hdb: setting 32-bit IO_support flag to 0 setting multcount to 16 setting unmaskirq to 1 (on) setting using_dma to 0 (off) multcount = 16 (on) IO_support = 0 (default 16-bit) unmaskirq = 1 (on) using_dma = 0 (off)
And again we time..
for i in $(seq 1 1 5);do;hdparm -Tt /dev/hdb;done /dev/hdb: Timing cached reads: 462 MB in 2.00 seconds = 230.67 MB/sec Timing buffered disk reads: 8 MB in 3.32 seconds = 2.41 MB/sec /dev/hdb: Timing cached reads: 430 MB in 2.00 seconds = 214.88 MB/sec Timing buffered disk reads: 8 MB in 3.12 seconds = 2.56 MB/sec /dev/hdb: Timing cached reads: 440 MB in 2.01 seconds = 219.28 MB/sec Timing buffered disk reads: 8 MB in 3.31 seconds = 2.42 MB/sec /dev/hdb: Timing cached reads: 472 MB in 2.01 seconds = 235.20 MB/sec Timing buffered disk reads: 8 MB in 3.17 seconds = 2.53 MB/sec /dev/hdb: Timing cached reads: 468 MB in 2.00 seconds = 233.77 MB/sec Timing buffered disk reads: 8 MB in 3.19 seconds = 2.51 MB/sec
Again not much of an increase in speed itself, but again the impact on the machine decreased
This one makes sense. This sets the drive's 32-bit I/O support. It makes sense that 32-bit I/O would be faster than 16-bit I/O. It should be noted that this option has 3 values. -c0 turns it off, -c1 enables it, and -c3 enables it with a sync sequence required by many drives, at the cost of slightly more overhead
hdparm -c3 -d0 -u1 -m16 /dev/hdb /dev/hdb: setting 32-bit IO_support flag to 3 setting multcount to 16 setting unmaskirq to 1 (on) setting using_dma to 0 (off) multcount = 16 (on) IO_support = 3 (32-bit w/sync) unmaskirq = 1 (on) using_dma = 0 (off)
Once more to the timings...
for i in $(seq 1 1 5);do;hdparm -Tt /dev/hdb;done /dev/hdb: Timing cached reads: 468 MB in 2.01 seconds = 233.32 MB/sec Timing buffered disk reads: 12 MB in 3.45 seconds = 3.48 MB/sec /dev/hdb: Timing cached reads: 470 MB in 2.00 seconds = 234.80 MB/sec Timing buffered disk reads: 12 MB in 3.35 seconds = 3.58 MB/sec /dev/hdb: Timing cached reads: 436 MB in 2.01 seconds = 217.35 MB/sec Timing buffered disk reads: 10 MB in 3.30 seconds = 3.03 MB/sec /dev/hdb: Timing cached reads: 444 MB in 2.01 seconds = 221.20 MB/sec Timing buffered disk reads: 12 MB in 3.41 seconds = 3.52 MB/sec /dev/hdb: Timing cached reads: 468 MB in 2.00 seconds = 233.64 MB/sec Timing buffered disk reads: 12 MB in 3.35 seconds = 3.59 MB/sec
This time we see some speed increases. Buffered Disk Reads increased to about 3.40 MB/sec
The best comes last. Turning on DMA is probably the reason most of us have heard of hdparm, with good reason. It gives the biggest boost out of all the hdparm tweaks. Activate it with the -d1 option
hdparm -d1 -c3 -u1 -m16 /dev/hdb /dev/hdb: setting 32-bit IO_support flag to 3 setting multcount to 16 setting unmaskirq to 1 (on) setting using_dma to 1 (on) multcount = 16 (on) IO_support = 3 (32-bit w/sync) unmaskirq = 1 (on) using_dma = 1 (on)
Now lets fire up the timings!
for i in $(seq 1 1 5);do;hdparm -Tt /dev/hdb;done /dev/hdb: Timing cached reads: 460 MB in 2.00 seconds = 229.60 MB/sec Timing buffered disk reads: 84 MB in 3.06 seconds = 27.42 MB/sec /dev/hdb: Timing cached reads: 456 MB in 2.01 seconds = 227.34 MB/sec Timing buffered disk reads: 84 MB in 3.03 seconds = 27.73 MB/sec /dev/hdb: Timing cached reads: 470 MB in 2.00 seconds = 234.93 MB/sec Timing buffered disk reads: 84 MB in 3.03 seconds = 27.73 MB/sec /dev/hdb: Timing cached reads: 462 MB in 2.00 seconds = 230.96 MB/sec Timing buffered disk reads: 84 MB in 3.06 seconds = 27.41 MB/sec /dev/hdb: Timing cached reads: 444 MB in 2.00 seconds = 221.87 MB/sec Timing buffered disk reads: 84 MB in 3.01 seconds = 27.87 MB/sec
Pretty damn good! Buffered disk reads increased almost 9-fold. Also there was almost no impact on system performance!
One more thing, how do you get the data? Easy
hdparm -I /dev/hdb /dev/hdb: ATA device, with non-removable media Model Number: WDC WD3000JB-00KFA0 Serial Number: WD-WMAMR1055762 Firmware Revision: 08.05J08 Standards: Supported: 6 5 4 Likely used: 6 Configuration: Logical max current cylinders 16383 65535 heads 16 1 sectors/track 63 63 -- CHS current addressable sectors: 4128705 LBA user addressable sectors: 268435455 LBA48 user addressable sectors: 586072368 device size with M = 1024*1024: 286168 MBytes device size with M = 1000*1000: 300069 MBytes (300 GB) Capabilities: LBA, IORDY(can be disabled) Standby timer values: spec'd by Standard, with device specific minimum R/W multiple sector transfer: Max = 16 Current = 16 Recommended acoustic management value: 128, current value: 254 DMA: mdma0 mdma1 mdma2 udma0 udma1 *udma2 udma3 udma4 udma5 Cycle time: min=120ns recommended=120ns PIO: pio0 pio1 pio2 pio3 pio4 Cycle time: no flow control=120ns IORDY flow control=120ns Commands/features: Enabled Supported: * SMART feature set Security Mode feature set * Power Management feature set * Write cache * Look-ahead * Host Protected Area feature set * WRITE_BUFFER command * READ_BUFFER command * DOWNLOAD_MICROCODE SET_MAX security extension * Automatic Acoustic Management feature set * 48-bit Address feature set * Device Configuration Overlay feature set * Mandatory FLUSH_CACHE * FLUSH_CACHE_EXT * SMART error logging * SMART self-test * SMART Command Transport (SCT) feature set * SCT Long Sector Access (AC1) * SCT LBA Segment Access (AC2) * SCT Error Recovery Control (AC3) * SCT Features Control (AC4) Security: Master password revision code = 65534 supported not enabled not locked not frozen not expired: security count not supported: enhanced erase HW reset results: CBLID- above Vih Device num = 1 determined by the jumper Checksum: correct