gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:47 25 4
gpt4 key购买 nike

我正在编写一个从标准输入读取并写入标准输出的 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);
}

我在 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,

32768, 5.27, 17.78,

65536, 5.22, 17.77,

131072, 5.52, 17.70,

262144, 5.60, 17.40,

524288, 5.96, 17.99,

由于我们使用了不同的 block 大小,所以我没有看到用户+系统时间有任何显着变化。但从理论上讲,随着 block 大小变小,相同文件大小会产生很多系统调用,执行时间应该会更长。我在理查德史蒂文斯的“Unix环境高级编程”一书中看到了类似测试的测试结果,它表明如果复制中使用的缓冲区大小接近 block 大小,用户+系统时间会显着减少。(在我的例子中, ext4 分区上的 block 大小为 4096 字节)

为什么我无法重现这些结果?我是否遗漏了这些测试中的某些因素?

最佳答案

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

如果您注释掉 #define您应该能够修复此错误。

想到的另一个方面:

如果你在一台机器上创建一个文件并在之后立即读取它,它将在操作系统的磁盘缓存中(它足够大以存储所有这个文件),所以实际的磁盘 block 大小不会有在这里影响很大。

Stevens 的书写于 1992 年,当时 RAM 比现在贵得多,因此其中的某些信息可能已经过时。我也怀疑这本书的新版本是否已经删除了这些内容,因为通常它们仍然是正确的。

关于linux - 确定在 linux 中读取文件的最佳缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50175688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com