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

时间:2014-12-15 19:09:16

标签: c benchmarking

我在C中编写了几个基准程序来完成以下任务:

  1. 可以从网络磁盘读取的速度。打印读取8192字节所需的秒数。
  2. 可以从本地计算机上的本地目录/ tmp读取的速度。打印读取8192字节所需的秒数。
  3. 可以从磁盘页缓存中读取的速度。打印读取8192字节所需的秒数。
  4. 可以写入网络磁盘的速度。打印写入8192字节所需的秒数。
  5. 可以写入本地计算机上本地目录/ tmp的速度。打印写入8192字节所需的秒数。
  6. 此处的目标是仅衡量执行文件读取或写入的时间(使用readwrite以避免来自fread的任何缓冲时间)

    我对1和2的一般方法是创建一个8192字节的文件并将其写入磁盘(无论是本地目录还是网络磁盘),然后调用sleep(10)等待页面缓存刷新,以便我测量实际I / O的时间,而不是缓存I / O.然后我测量空循环数千次所需的时间,然后读取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 个答案:

答案 0 :(得分:1)

以下是我的文件读取功能,可以选择是否使用基于内存的缓存。如果首先编写文件,则需要类似的开放语句。请注意,无法通过LAN使用直接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;
}