当前位置: 技术问答>linux和unix
linux文件direct io读取为何效率比非direct io低很多,请专家指点?
来源: 互联网 发布时间:2016-05-12
本文导语: 使用如下两种方式进行大尺寸文件顺序读取和随机读取,测试发现不使用Direct io方式打开文件进行读取效率反而很高。 不知为何?请专家指点。 char * realbuff; posix_memalign( (void**)&realbuff, 512, BUFFER_SIZE )...
使用如下两种方式进行大尺寸文件顺序读取和随机读取,测试发现不使用Direct io方式打开文件进行读取效率反而很高。
不知为何?请专家指点。
char * realbuff;
posix_memalign( (void**)&realbuff, 512, BUFFER_SIZE );
#ifdef DIRECT_IO
fp = open("xxx.tar", O_RDONLY|O_DIRECT)
#else
fp = open("xxx.tar", O_RDONLY)
#endif
read(fp, realbuff, BUFFER_SIZE);
测试发现,被读文件尺寸14687917字节,连续读取10次。
direct io方式:读取需要接近3秒。
非direct io: 读取0.8秒。
不知为何?请专家指点。
char * realbuff;
posix_memalign( (void**)&realbuff, 512, BUFFER_SIZE );
#ifdef DIRECT_IO
fp = open("xxx.tar", O_RDONLY|O_DIRECT)
#else
fp = open("xxx.tar", O_RDONLY)
#endif
read(fp, realbuff, BUFFER_SIZE);
测试发现,被读文件尺寸14687917字节,连续读取10次。
direct io方式:读取需要接近3秒。
非direct io: 读取0.8秒。
|
你在使用标准IO库接接口前使用setvbuf()设置一下缓冲长度,然后direct IO也使用这个缓冲长度看一看,应该是差不多的。标准IO库的输入输出接口最终都是要调用系统接口的,只是当带缓冲时并不是你每一次调用标准IO接口都会有一个相应的系统IO调用,是当你缓冲区满的时候还进行一次系统IO调用。谭浩强的书可能没有对系统调用跟标准库接口进行区分吧.
|
O_DIRECT是控制内核系统调用是否缓存,如果O_DIRECT,内核设置DMA直接到用户空间buffer,不在内核设置缓存区。
fopen是C库函数,不管底层什么样,它自己提供用户空间缓存。
O_DIRECT选项被人诟病,推荐使用的是posix_fadvise或madvise。
fopen是C库函数,不管底层什么样,它自己提供用户空间缓存。
O_DIRECT选项被人诟病,推荐使用的是posix_fadvise或madvise。
|
fopen跟操作系统无关,是C库自己提供缓存的,是用户空间缓存。
谭是从C库的角度讲,C库的open不做缓存,fopen做。二者的实现都是调用系统调用open,C库的open和系统调用的open是两个层面的东西。
系统调用的open必须用O_DIRECT才不缓存。
open比fopen高,是因为fopen多了一次缓存拷贝。
谭是从C库的角度讲,C库的open不做缓存,fopen做。二者的实现都是调用系统调用open,C库的open和系统调用的open是两个层面的东西。
系统调用的open必须用O_DIRECT才不缓存。
open比fopen高,是因为fopen多了一次缓存拷贝。
|
这个测试受到很多地方的影响,比如硬盘驱动器自身的缓存机制。
还有操作系统对近期访问过的文件有优化下次访问的机制。
要测试的话,每次测试必须要关闭机器,然后重新开机。才能获得比较准确的结果。
理论上来说,只要缓冲区设置的合理,应该是直接的OPEN效率高点的。
个人想法,可能有不对的地方。
还有操作系统对近期访问过的文件有优化下次访问的机制。
要测试的话,每次测试必须要关闭机器,然后重新开机。才能获得比较准确的结果。
理论上来说,只要缓冲区设置的合理,应该是直接的OPEN效率高点的。
个人想法,可能有不对的地方。
|
标准IO库为你选取了最佳的缓冲区长度,而直接IO不会。