如何测量文件I/O的墙钟时间

3
我正在用C语言编写多个基准测试程序来完成以下任务:
1. 从网络磁盘读取数据的速度。打印读取8192字节所需的秒数。 2. 从本地计算机上的/tmp目录读取数据的速度。打印读取8192字节所需的秒数。 3. 从磁盘页缓存读取数据的速度。打印读取8192字节所需的秒数。 4. 向网络磁盘写入数据的速度。打印写入8192字节所需的秒数。 5. 向本地计算机上的/tmp目录写入数据的速度。打印写入8192字节所需的秒数。
这里的目标是仅测量执行文件读取或写入操作所需的时间(使用read和write函数,避免fread的任何缓冲时间)。
我的一般做法是创建一个8192字节的文件并将其写入磁盘(无论是本地目录还是网络磁盘),然后调用sleep(10)等待页面缓存刷新,以便衡量实际I/O而不是缓存I/O的时间。然后我测量执行空for循环需要的时间,接着测量读取8192字节所需的时间,再减去两者之间的时间差,最后除以所有迭代中的平均值。我的代码如下:
struct timespec emptyLoop1, emptyLoop2;
clock_gettime(CLOCK_REALTIME, &emptyLoop1);
for(i = 0, j = 0; i < ITERATIONS; i++) {
    j+=i*i;
}
clock_gettime(CLOCK_REALTIME, &emptyLoop2);
char readbuf[NUM_BYTES];

struct timespec beforeRead, afterRead;
clock_gettime(CLOCK_REALTIME, &beforeRead);
for(i = 0, j = 0; i < ITERATIONS; i++){
    j+=i*i;
    read(fd, readbuf, NUM_BYTES);
}

这是否足以准确测量从这些位置读取的时间?

接下来,我对如何从页面缓存中读取感到困惑。它在磁盘上的哪个位置存在,我该如何访问它?最后,在4和5方面有一些技巧,它们显然比看起来要难得多,但我不确定我错过了什么。


关于1和2:请查看这里 关于4和5:您应该刷新缓冲区以实际写入(主要是针对本地目录)。请查看_fflush_的手册页面。 - delirium
1
关于1,2和3:在第一次读取网络驱动器和本地驱动器后,它们不就已经在内存缓存中了吗? - Weather Vane
1个回答

1
以下是我的文件读取函数,可以选择使用或不使用基于内存的缓存。如果首先要写入文件,则需要类似的打开语句。请注意,在局域网上无法使用直接I/O,并且缓存可能是不可预测的。更多详细信息以及源代码和执行文件的访问方式,请参见http://www.roylongbottom.org.uk/linux_disk_usb_lan_benchmarks.htm
int readFile(int use, int dsize)
{
    int p;

    if (useCache)
    {
          handle = open(testFile, O_RDONLY);
    }
    else
    {
          handle = open(testFile, O_RDONLY | O_DIRECT);
    }

    if (handle == -1)
    {
        printf (" Cannot open data file for reading\n\n");
        fprintf (outfile, " Cannot open data file for reading\n\n");
        fclose(outfile);
        printf(" Press Enter\n");
        g  = getchar();
        return 0;
    }

    for (p=0; p<use; p++)
    {
        if (read(handle, dataIn, dsize) == -1)
        {
            printf (" Error reading file\n\n");
            fprintf (outfile, " Error reading file\n\n");
            fclose(outfile);
            close(handle);
            printf(" Press Enter\n");
            g  = getchar();
            return 0;
        }           

    }
    close(handle);
    return 1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接