【发布时间】:2015-04-14 20:31:31
【问题描述】:
这是我用来计算从文件中读取不同字节数所花费的时间的代码。
for(int i = 0; i < TRIALS; i++){
fd = open(argv[1], O_RDONLY);
//Set the file offset to a random position on the file
//But still a multiple of the current current test block size,
//Simulating jumps of the given test block size
//trying to avoid prefetch
lseek(fd, test_block * rand() % (fs / test_block), SEEK_SET);
//How much time takes to read `test_block` bytes
clock_gettime(CLOCK_MONOTONIC, &ts_ini);
ssize_t bytes_read = read(fd, buffer, test_block);
clock_gettime(CLOCK_MONOTONIC, &ts_end);
if(bytes_read > 0){
accum += (((double)(ts_end.tv_sec - ts_ini.tv_sec)) +
(ts_end.tv_nsec - ts_ini.tv_nsec)/NANO_TO_SEC) / TRIALS;
}
//Closing the file after each trial to release resources
close(fd);
}
现在,如果我用这个小 shell 脚本运行这个程序:
echo "Block Size(bytes) | Avg. Time(seconds)"
for block in 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
do
./bin/blocksize /tmp/random_gen $block
done
我得到这个结果:
Block Size(bytes) | Avg. Time(seconds)
4 | 0.002927567500
8 | 0.003120735600
16 | 0.004888980800
32 | 0.003885210600
64 | 0.003578379700
128 | 0.001272970500
256 | 0.004926633700
512 | 0.001281894000
1024 | 0.000243394200
2048 | 0.000175361100
4096 | 0.000001048200
8192 | 0.000001938000
16384 | 0.000003214000
有了这个结果,我假设我系统的块大小是 4096 字节(这与 dumpe2fs 一致),因为此时它不需要做任何额外的操作,只需传递它的块从文件中获取,因此非常快,之后时间重复。 (这是我的猜测)
但这里是奇怪的部分,如果我稍微修改一下 sh 脚本,在每次执行之前添加以清理缓存,如下所示:
echo "Block Size(bytes) | Avg. Time(seconds)"
for block in 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
do
echo "echo 3 > /proc/sys/vm/drop_caches" | sudo sh
./bin/blocksize /tmp/random_gen $block
done
然后发生这种情况:
Block Size(bytes) | Avg. Time(seconds)
4 | 0.006217417300
8 | 0.003913319300
16 | 0.004674101500
32 | 0.005444699600
64 | 0.005125086700
128 | 0.004965967700
256 | 0.002433360800
512 | 0.002100266600
1024 | 0.002221131400
2048 | 0.001623008600
4096 | 0.001936151500
8192 | 0.001391976900
16384 | 0.001270749800
这对我来说没有任何意义。为什么当我先清理缓存时,随着测试块大小的增加,时间不断减少?
在 Ubuntu 14.04LTS 64 位上运行
【问题讨论】:
-
不确定这是否按您的预期工作。您的磁盘驱动器确实有大量您没有考虑到的缓存?您可能会通过重复读取相同扇区来启动硬件的缓存算法?
标签: c linux unix operating-system