Measure the performance of the TRIM command on your SSD
TRIM is a command that is supported by modern SSDs. With the TRIM command the filesystem can tell an SSD that a specific block is no longer in use. This way the internal wear leveling and garbage collecting algorithms don't have to deal with the remaining data, and they can erase that block at their own leisure. If blocks that are not used by the filesystem are not erased regularly, then with time, more and more writes to the disk will need to do a read-erase-write cycle, and that slows down SSD write performance. TRIM is designed to keep the drive at high performance levels for a much longer time.
The TRIM command needs operating system support. Windows 7 and later support it. In Linux you basically have two choices:
- Use "fstrim /path/to/mountpoint" (in debian it's in the util-linux package). This will simply trim all the free space on the filesystem. This is something that should be run periodically, for example using cron.
- Or mount your filesystem using the "-o discard" option. This will call the trim command automatically after you delete something. This can slow down the speed of deleting files, for some filesystem-ssd combinations just a little bit, or for some other filesystem-ssd combinations, a lot.
I wrote this little tool, trim_perf.c , to measure how much the trim command takes to run, based on block size. It starts out with a block size of 2 GiB (4194304 sectors), and keeps halfing it until it reaches one sector. So this trims around 4 GiB of data from the start of whatever blockdevice you give it. So Warning! This little performance testing tool is very destructive to your data. Use it only on SSDs that don't have any data you need, because everything, including the partition table, will be deleted!
I wrote this little tool because recently I stumbled upon the same performance problem as described in this post. More specifically deleting a linux kernel source tree takes about 1 second on ext4, but it takes more then 6 minutes on xfs, on my OCZ Agility 3. On the other hand, my other drive (Corsair Performance Pro) preforms well with both filesystems. As you can see from the chart, the OCZ Agility 3 is far slower at trimming small blocks then the Corsair SSD. More then 100 times slower.
What XFS does when mounted with "-o discard" (at least the versions that are in the 3.1 kernels) is that it issues many small TRIM commands, instead of a few big ones. XFS trims blocks with an average size of 13.2 KiB (26.48 sectors), while ext4 uses an average size of 21 MiB (43036 sectors). Also XFS issues the TRIM command 1641 more times then ext4 does. I found this out by adding a printk to the blkdev_issue_discard() call in block/blk-lib.c in the kernel to see what size blocks are discarded during one call to this function.