APUE编程:13---文件I/O之(I/O的效率)
原创
©著作权归作者所有:来自51CTO博客作者董哥的黑板报的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、来看一个例子
- 下面的程序从标准输入获取数据,然后将内容输出到标准输出中:
#include <stdio.h>
#include <unistd.h>
#define BUFFSIZE 4096
int main()
{
int n;
char buf[BUFFSIZE];
while((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
if(write(STDOUT_FILENO, buf, n) != n)
perror("write error");
if(n > 0)
perror("read error");
return 0;
}
- 它从标准输入读、写到标准输出,这就界定它执行本程序之前,这些标准输入、输出已由shelle安排好。确实,所有常用的UNIX系统shell都提供了一种方法,它在标准输入上打开一个文件用于读,在标准输出创建(或重写)一个文件。这使得程序不必打开输入和输出文件,并允许用户利用shell的I/O重定向功能
- 考虑到进程终止时,UNIX系统内核会关闭进程的所有打开的文件描述符,因此本程序并不关闭输入和输出文件
- 对UNIX系统内核而言,文本文件和二进制代码文件并无区别,所以本程序对这两种文件都有效
二、缓冲区的取值分析
- 上面的程序read()和write()用到的缓冲区大小由定义的BUFFSIZE常量决定
- 下面显示了用20种不同的缓冲区长度,读516581760字节的文件所得到的的结果
- 测试环境:我们运行上面的程序,其标准输出被重定向到/dev/null上,测试的文件系统为ext4文件系统,磁盘块长度为4096字节(磁盘块长度由st_blksize表示。这也证明了上图中系统CPU时间的几个最小值差不多出现在BUFFSIZE为4096及以后的位置,继续增加缓冲区的长度对此时间几乎没有影响
三、预读技术
- 大多数文件系统为改善性能都采用某种预读(read ahead)技术。当检测到正进行顺序读取时,系统就试图读入比应用程序要求的更多数据,并假想应用很快就会读这些数据
- 预读的结果可以从上图看出,缓冲区长度小至32字节的时钟时间比拥有较大缓冲区长度时的时钟时间几乎一样
四、总结
- “说明同步写的效果”一文中引用到本文
- “比较不带缓冲的I/O时间与标准I/O库所用的时间”一文中引用到本文