Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1779894
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-28 12:55:02

下面的代码只使用read和write函数复制一个文件。


  1. #include <unistd.h>

  2. #define BUFFSIZE 4096

  3. void err_sys(const char* msg);

  4. int
  5. main(void)
  6. {
  7.     int n;
  8.     char buf[BUFFSIZE];

  9.     while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
  10.         if (write(STDOUT_FILENO, buf, n) != n)
  11.             err_sys("write error");

  12.     if (n < 0)
  13.         err_sys("read error");

  14.     exit(0);
  15. }

1、这段代码假设程序启动前标准输出和标准输入都已经被shell设置好,并从标准输入读入,而后写出到标准输出。确实,所有一般的UNIX系统shell提供打开一个文件以从标准输入中读取和为标准输出创建或覆写一个文件的方法。这样程序就不必打开输入和输出的文件。

2、许多程序都假设标准输入的文件描述符是0而标准输出的文件描述符为1。在这个例子里,我们使用了两个在定义的名字:STDIN_FILENO和STDOUT_FILENO。

3、程序必没有关闭输入或输出文件,相反,程序使用了特性:当进程终止时,UNIX内核会关闭所有打开的文件描述符。

4、这个例子对于文本文件和字节文件都可以工作,因为对于UNIX内核两者没有任何区别。


我们仍有一个没有回答的问题:我们如何来选取BUFFSIZE的值?在回答这个问题之前,让我们用不同的BUFFSIZE值来运行下这个程序。我们使用上 面的程序,把标准输出重定向到/dev/null。测试使用使用4,096字节的块的Linux ext2文件系统。下表显示了用20个不同的buffer值读取一个103,316,352字节的文件的结果:

在Linux上使用不同的buffer大小读取文件的结果
BUFFSIZE
用户CUP(秒数)
系统CPU(秒数)
时钟时间(秒数)
循环数
1 124.89 161.65 288.64 103,316,352
2 63.10 80.96 145.81 51,658,176
4 31.84 40.00 72.75 25,829,088
8 15.17 21.01 36.85 12,914,544
16 7.86 10.27 18.76 6,457,272
32 4.13 5.01 9.76 3,228,636
64 2.11 2.48 6.76 1,614,318
128 1.01 1.27 6.82 807,159
256 0.56 0.62 6.80 403,579
512 0.27 0.41 7.03 201,789
1,024 0.18 0.23 7.84 100,894
2,048 0.05 0.19 6.82 50,447
4,906 0.03 0.16 6.86 25,223
8,192 0.01 0.18 6.67 12,611
16,384 0.02 0.18 6.87 6,305
32,768 0.00 0.16 6.70 3,152
65,536 0.02 0.19 6.92 1,576
131,072 0.00 0.16 6.84 788
262,144 0.01 0.25 7.30 394
524,288 0.00 0.22 7.35 198

可以看到当BUFFSIZE为4,096时,有一个最小的系统时间,超过这个大小的buffer没有更好的效果。


多数文件系统支持某种超前读入的方法来提高性能。当发现有一连串的读操作时,系统尝试读入比系统请求更多的数据,假设程序会在不久后读到它们。从上表中最后几行可以看到,在超过128K后ext2的超前读入就不再有效果了。


我们待会再回来讨论这个时间例子。在3.14节我们会展示同步写的效果;在5.8节我们会比较这些未缓冲I/O时间和标准I/O库。


当尝试测量读写文件的程序的性能时要注意,操作系统会尝试把文件缓存到主内存(incore,意思为main memory,过去系统主内存是用铁核--ferrite core做成的,这也是术语“core dump”的由来:一个程序的主内存映象存储到磁盘上的一个文件用来诊断),所以当你重复地测量这个程序的性能时,后面的时间会比第一次要少。这时因为第 一次运行会导致文件被缓存到系统缓存中,而后续运行会从系统缓存而不是硬盘里访问文件。


在上表中的测试里,每次不同buffer尺寸的运行都是使用文件的不同拷贝,这样当前运行就不会找到上次运行的缓存数据。这些文件都已经有足够大,没有全部留在缓存中。(测试系统的配置是512M的RAM)。


阅读(874) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~