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

我正在编写一个从stdin读取并写入stdout的C程序。但它会缓冲数据,以便仅在读取特定数量的字节后才执行写操作(= SIZE)


#include<stdio.h>

#include<stdlib.h>


#define SIZE 100


int 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=$2


echo "Test Data" >testData

echo "Step Size:(doubles from previous size) Start Size:$2 Stop Size:$3" >>testData


while [ $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 testFile

done

我正在测量执行程序并将其制成表格所需的时间。测试运行将产生以下数据:


Test Data

Step Size:(doubles from previous size) Start Size:1 Stop Size:524288


1,      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字节)


为什么我无法重现这些结果?我在这些测试中是否缺少一些因素?


MM们
浏览 309回答 1
1回答

千万里不及你

您没有#define SIZE 100在源代码中禁用该行,因此通过option(-DSIZE=1000)进行的定义仅在此之上有影响#define。在我的编译器上,我<command-line>:0:0: note: this is the location of the previous definition在编译时收到有关此()的警告。如果您将其注释掉,则#define应该可以修复此错误。我想到的另一个方面是:如果您在计算机上创建文件并随后立即读取文件,则该文件将位于操作系统的磁盘缓存中(该磁盘足够存储所有文件),因此实际磁盘块大小不会占用太多空间。影响在这里。史蒂文斯(Stevens)的书写于1992年,当时RAM的价格要比今天贵得多,因此其中的某些信息可能已经过时了。我也怀疑本书的新版本是否将此类内容排除在外,因为总的来说它们仍然是正确的。
打开App,查看更多内容
随时随地看视频慕课网APP