前言:上高级操作系统的课时老师要求写这个程序作为课堂作业,测试不同buffsize对文件读写的性能影响,虽然书上有个比较像的代码,但还是有些不同,遂记(水)之。
要求命令格式: ./file_io buffsize
其中buffsize是缓冲大小,操作系统读写文件的性能很大一部分取决于这个缓冲区,缓冲区很小的话,对大文件,再快的CPU也慢得一*。下面是两个测试例子,以1和2048缓冲大小为例。
time ./file_io 1 < ./test.data > ./res_buf_.txt
time ./file_io 2048 < ./test.data > ./res_buf_.txt
懂命令的请直接看代码或者结论。其中time是UNIX/Linux的内置函数,记录一个进程执行过程中在用户态和系统态分别所花的时间,左括号和右括号是输入输出重定向,前者表示将test.data文件作为输入源,后者表示将程序的输出重定向到res_buf_.txt文件中。
代码
既然是测试,那首先得准备测试数据,考虑到最近几年的硬件都很快了,测试数据当然也得很大,小的测试数据体现不出由buffsize的不同带来的差距,直接下手狠一点,准备一个行×
列的字符矩阵作为测试数据,算下来这个文件一共占了859MB空间,应该算是很大了。(注:环境为Ubuntu20.04)
makeTestData.c
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp = fopen("./test.data", "w");
if(fp == NULL){
exit(0);
}
long long length = 1e8 * 9;
char p[1000000] = {'x'};
p[999999] = '0';
for (long long i = 0; i < length; i++){
fputs(p, fp);
}
fclose(fp);
return 0;
}
准备好了测试数据,接下来就是关键程序了,apue.h可以不用include,这是UNIX高级编程那本书的作者写的配套库,里面好多自定义的函数,err_sys就是其中之一,这里不知道为啥已经include了但直接用就会编译报错,但用里面的其他函数就没问题,索性就直接在当前文件里直接重写了。
file_io.c
#include"include/apue.h"
#include<stdlib.h>
#include<stdio.h>
void err_sys__(char *p);
int main(int argc, char *argv[])
{
int n = 0;
int buffsize = atoi(argv[1]); //读入并转换命令行给的buffsize参数的类型
char buf[buffsize];
while((n = read(STDIN_FILENO, buf, buffsize)) > 0){
if(write(STDOUT_FILENO, buf, n) != n){
err_sys__("write error");
}
}
if(n < 0){
err_sys__("read error!");
}
return 0;
}
void err_sys__(char *p)
{
printf("%s", p);
}
测试性能,当然不能让buffsize直接从1到2048,心急吃不了热豆腐,当然得慢慢来,经典每次翻一倍,写一个sh脚本,让它自己慢慢跑:
test.sh
time ./file_io 1 < ./test.data > ./res_buf_.txt
time ./file_io 2 < ./test.data > ./res_buf_.txt
time ./file_io 4 < ./test.data > ./res_buf_.txt
time ./file_io 8 < ./test.data > ./res_buf_.txt
time ./file_io 16 < ./test.data > ./res_buf_.txt
time ./file_io 32 < ./test.data > ./res_buf_.txt
time ./file_io 64 < ./test.data > ./res_buf_.txt
time ./file_io 128 < ./test.data > ./res_buf_.txt
time ./file_io 256 < ./test.data > ./res_buf_.txt
time ./file_io 512 < ./test.data > ./res_buf_.txt
time ./file_io 1024 < ./test.data > ./res_buf_.txt
time ./file_io 2048 < ./test.data > ./res_buf_.txt
结果
测试过程的速度受硬件CPU、缓存、内存、磁盘等因素的影响很大,以我拯救者R7000 2020为例,CPU是AMD锐龙4600H,测试结果如下图,每两行是表示一个buffsize的测试结果,可以看到操作系统在系统态的时间占了大多数,而且随着缓存大小的成倍增加,系统态和用户态用时也差不多成倍的减少,符合预期。