【发布时间】:2018-10-14 23:40:17
【问题描述】:
我正在编写一个从标准输入读取并写入标准输出的 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,
由于我们使用不同的块大小,我没有看到用户+系统时间有任何显着变化。但理论上,随着块大小变小,同样大小的文件会产生很多系统调用,执行时间应该会更长。我在 Richard Stevens 的“Unix 环境中的高级编程”一书中看到了类似测试的测试结果,它表明如果复制中使用的缓冲区大小接近块大小,则用户+系统时间会显着减少。(在我的情况下, ext4 分区上的块大小为 4096 字节)
为什么我无法重现这些结果?我在这些测试中遗漏了一些因素吗?
【问题讨论】:
-
谢谢@Alfe。正如您之前提到的,问题是当我通过编译器传递参数时,SIZE 的默认值没有被覆盖。注释掉#define SIZE 100 有帮助。观察结果与史蒂文斯获得的结果相似。随着我们接近 4096 及更大的块大小,从文件读取所需的时间大大减少。
-
(我将我的 cmets 迁移到了正确的答案中。)
-
您能否使用更新的结果发布答案(或更新问题)。这是一个常见的用例,拥有这些数据会很棒
标签: linux performance unix filesystems system-calls