为了账号安全,请及时绑定邮箱和手机立即绑定

确定在Linux中读取文件的最佳缓冲区大小

确定在Linux中读取文件的最佳缓冲区大小

MM们 2021-04-09 14:11:59
我正在编写一个从stdin读取并写入stdout的C程序。但它会缓冲数据,以便仅在读取特定数量的字节后才执行写操作(= SIZE)#include<stdio.h>#include<stdlib.h>#define SIZE 100int main(){        char buf[SIZE];        int n=0;        //printf("Block size = %d\n", BUFSIZ);        while( ( n = read(0, buf, sizeof(buf)) ) > 0 )                write(1, buf, n);        exit(0);}Iam在Oracle Virtual Box(4GB RAM,2个内核)上托管的Ubuntu 18.04上运行该程序,并测试该程序的缓冲区大小是否不同。我已经将标准输入重定向到来自文件(包含动态创建的随机数)的文件,并将标准输出重定向到/ dev / null。这是用于运行测试的shell脚本:#!/bin/bash# $1 - step size  (bytes)# $2 - start size (bytes)# $3 - stop size (bytes)echo "Changing buffer size from $2 to $3 in steps of $1, and measuring time for copying."buff_size=$2echo "Test Data" >testDataecho "Step Size:(doubles from previous size) Start Size:$2 Stop Size:$3" >>testDatawhile [ $buff_size -le $3 ]do        echo "" >>testData        echo -n "$buff_size," >>testData        gcc -DSIZE=$buff_size copy.c    # Compile the program for cat, with new buffer size        dd bs=1000 count=1000000 </dev/urandom >testFile        #Create testFile with random data of 1GB                (/usr/bin/time -f "\t%U, \t%S," ./a.out <testFile 1>/dev/null) 2>>testData        buff_size=$(($buff_size * 2))        rm -f a.out        rm -f testFiledone我正在测量执行程序并将其制成表格所需的时间。测试运行将产生以下数据:Test DataStep Size:(doubles from previous size) Start Size:1 Stop Size:5242881,      5.94,   17.81,2,      5.53,   18.37,4,      5.35,   18.37,8,      5.58,   18.78,16,     5.45,   18.96,32,     5.96,   19.81,64,     5.60,   18.64,128,    5.62,   17.94,256,    5.37,   18.33,512,    5.70,   18.45,1024,   5.43,   17.45,2048,   5.22,   17.95,4096,   5.57,   18.14,8192,   5.88,   17.39,16384,  5.39,   18.64,由于我们使用不同的块大小,因此我看不到用户+系统时间有任何重大变化。但是从理论上讲,随着块大小变小,对于相同的文件大小会生成许多系统调用,并且执行起来将花费更多时间。我在理查德·史蒂文斯(Richard Stevens)的《 Unix环境中的高级编程》一书中看到了类似测试的测试结果,该结果表明,如果复制中使用的缓冲区大小接近块大小,则用户+系统时间将大大减少。 ext4分区上的块大小为4096字节)为什么我无法重现这些结果?我在这些测试中是否缺少一些因素?
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

您没有#define SIZE 100在源代码中禁用该行,因此通过option(-DSIZE=1000)进行的定义仅在此之上有影响#define。在我的编译器上,我<command-line>:0:0: note: this is the location of the previous definition在编译时收到有关此()的警告。

如果您将其注释掉,则#define应该可以修复此错误。

我想到的另一个方面是:

如果您在计算机上创建文件并随后立即读取文件,则该文件将位于操作系统的磁盘缓存中(该磁盘足够存储所有文件),因此实际磁盘块大小不会占用太多空间。影响在这里。

史蒂文斯(Stevens)的书写于1992年,当时RAM的价格要比今天贵得多,因此其中的某些信息可能已经过时了。我也怀疑本书的新版本是否将此类内容排除在外,因为总的来说它们仍然是正确的。


查看完整回答
反对 回复 2021-04-16
  • 1 回答
  • 0 关注
  • 304 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信