写了一个测试磁盘寻道(+旋转)时间的程序,方法如下:创建一个大文件(如果太小,文件所有内容都在一个磁道上),使O_DIRECT打开文件,随机选择一个位置(4k的倍数),读取4K(文件系统块)大小的数据。
测试程序分别执行1、10、100、1000、10000次随机读文件操作,结果发现在1000次以内,消耗的时间总是1-3ms,超过10000才会略有大的增长,但也在1s范围内。发现DIRECTIO根本没有生效,百思不得其解。
仔细阅读了man手册上关于O_DIRECT的说明:
Try to minimize cache effects of the I/O toand from this file. In general this will degrade performance, but it isuseful in special situations, such as when applications do their owncaching. File I/O is done directlyto/from user space buffers. The I/O issynchronous, i.e., at the completion of a read(2) or write(2), data is guaranteed to have been transferred. Under Linux 2.4transfer sizes, and the alignment of user buffer and file offset must all bemultiples of the logical block size of the file system. Under Linux 2.6alignment to 512-byte boundaries suffices.
使用DIRECTIO要求缓冲区、offset跟块大小对齐,而程序中的缓冲区在栈上分配的,块对齐的几率很低。怎么保证内存跟块大小(4096B)对齐呢?man posix_memalign。
intposix_memalign(void **memptr, size_t alignment, size_t size);
void*memalign(size_t boundary, size_t size);
经过修改后,程序工作正常,测试结果如下:执行10000次随机读请求,平均读时间为3.6ms,因为文件的顺序性,这里测试的随机性不是太好。
参考资料:
http://www.ukuug.org/events/linux2001/papers/html/AArcangeli-o_direct.html
http://ender.hitidea.org/tag/o_direct/