写入大文件时带宽读数增加
Bandwidth readings increase while writing large file
我们一直在使用 gettimeofday
在 class 中测量两个外部 HDD 的带宽。
令人惊讶的是,在重复几次(每次执行三次测量,执行三次)之后,我们发现在两个 HDD 上写入一个 2500MB 的文件比写入一个较小的文件要快。
这是我们的 C 代码。它从 python 脚本调用以生成一些图表。
//argv[1] = path, argv[2] = size in MB (2500 in this case)
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
struct timeval tv0;
struct timeval tv1;
int main(int argc, char *argv[]){
unsigned long size=atoi(argv[2])*1000L*1000L;
int f = open(argv[1], O_CREAT|O_WRONLY|O_TRUNC, 0777);
char * array = malloc(size);
gettimeofday(&tv0, 0); //START TIME
write(f, array, size);
fdatasync(f);
close(f);
gettimeofday(&tv1, 0); // END TIME
double seconds = (((double)tv1.tv_sec*1000000.0 + (double)tv1.tv_usec) - ((double)tv0.tv_sec*1000000.0 + (double)tv0.tv_usec))/1000000.0;
printf("%f",seconds);
}
老师不知道,所以我在这里问:有没有可能发生这种情况的原因?
您的基准测试存在严重缺陷:
- 它假定它的所有函数调用都成功且没有错误。
- 它假设成功后,
write()
将写入指定的全部字节数,但这绝不是保证。
如果你的假设不被满足,那么其中任何一个都可能很容易使你的基准测试结果无效,至少第二个很可能是这样。
请特别注意 write()
returns 写入的字节数,如 ssize_t
。 ssize_t
是一个有符号整数类型,其具体宽度取决于系统。如果你的大小是 32 位,那么 write()
不能 在一次调用中写入所有 2500MB 缓冲区,因为这比带符号的 32 位整数可以表示的字节多(限制有点超过 2100 MB)。
此外,您的程序假定它可以成功分配非常大的内存块,但很容易证明并非如此。但是,如果这个假设失败了,你可能会得到崩溃的回报。
我们一直在使用 gettimeofday
在 class 中测量两个外部 HDD 的带宽。
令人惊讶的是,在重复几次(每次执行三次测量,执行三次)之后,我们发现在两个 HDD 上写入一个 2500MB 的文件比写入一个较小的文件要快。
这是我们的 C 代码。它从 python 脚本调用以生成一些图表。
//argv[1] = path, argv[2] = size in MB (2500 in this case)
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
struct timeval tv0;
struct timeval tv1;
int main(int argc, char *argv[]){
unsigned long size=atoi(argv[2])*1000L*1000L;
int f = open(argv[1], O_CREAT|O_WRONLY|O_TRUNC, 0777);
char * array = malloc(size);
gettimeofday(&tv0, 0); //START TIME
write(f, array, size);
fdatasync(f);
close(f);
gettimeofday(&tv1, 0); // END TIME
double seconds = (((double)tv1.tv_sec*1000000.0 + (double)tv1.tv_usec) - ((double)tv0.tv_sec*1000000.0 + (double)tv0.tv_usec))/1000000.0;
printf("%f",seconds);
}
老师不知道,所以我在这里问:有没有可能发生这种情况的原因?
您的基准测试存在严重缺陷:
- 它假定它的所有函数调用都成功且没有错误。
- 它假设成功后,
write()
将写入指定的全部字节数,但这绝不是保证。
如果你的假设不被满足,那么其中任何一个都可能很容易使你的基准测试结果无效,至少第二个很可能是这样。
请特别注意 write()
returns 写入的字节数,如 ssize_t
。 ssize_t
是一个有符号整数类型,其具体宽度取决于系统。如果你的大小是 32 位,那么 write()
不能 在一次调用中写入所有 2500MB 缓冲区,因为这比带符号的 32 位整数可以表示的字节多(限制有点超过 2100 MB)。
此外,您的程序假定它可以成功分配非常大的内存块,但很容易证明并非如此。但是,如果这个假设失败了,你可能会得到崩溃的回报。