文件I / O性能太好了,无法实现?

时间:2017-08-24 15:45:40

标签: c performance file io

我运行了一个简单的文件I / O性能测试。我将1GB数据写入文件并测量经过的时间。结果显示写入时间仅需0.45秒,性能超过17Gbps。我知道这是不可能的,但我的测试代码中找不到任何错误。以下是我的测试程序。我可以在d:\ a.bin中看到正确的文件。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    char *ioBuf;
    int i, io_buf_size = 1024 * 1024;
    unsigned int io_amt = 0;
    FILE *fp;
    clock_t start, end;
    double elapsed;

    ioBuf = (char *)malloc(1024 * 1024 * sizeof(char));

    for (i = 0; i < io_buf_size; i++) {
        ioBuf[i] = i % 255;
    }

    if ((fp = fopen("d:\\a.bin", "wb")) == NULL) {
        printf("open file fail, err  \n");
        return 1;
    }

    start = clock();
    for (i = 0; i < 1024; i++) {
        io_amt += fwrite(ioBuf, sizeof(char), io_buf_size, fp);
        if (fflush(fp) != 0) printf("flushing buffer failed!\n");
    }
    end = clock();
    elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    printf("fwrtie %dGB takes : %f sec\n", io_amt / (1024 * 1024 * 1024), elapsed);

    fclose(fp);
    free(ioBuf);
    return 0;
}

1 个答案:

答案 0 :(得分:4)

操作系统通常会将写入缓存在RAM中并仅在经过一段时间(通常以秒为单位)测量后将其写出(具体取决于具体的操作系统配置)。除此之外,即使您的磁盘驱动器也可能具有RAM缓存 1

如果您编写足够的数据(例如,超过您拥有的RAM数量),您会看到在某些时候显着减速,因为操作系统现在必须同步写出文件数据到为你的新写作留出空间。

请注意,此操作系统级别的缓存与执行fwrite时标准库可能执行的缓存不同 - 您正在编写1 MB块,因此可能没有看到标准库缓存,并且在任何情况下,当您fclose()文件时,将刷新这些缓冲区。

要衡量真正的速度,您有多种选择。假设您使用的是类似Linux的POSIX系统,则可以在fsync上获得的整数文件描述符上使用fileno。这将刷新操作系统缓冲区并指示磁盘写出任何非持久磁盘缓冲区。或者完全放弃C库f*函数并使用操作系统级例程打开文件O_DIRECT

最后,如评论中所述,文件的内容是一个简单的重复模式(周期为255个字节)。使用压缩或重复数据删除的文件系统可以轻松地将此文件存储在其标称大小的小部分中,从而导致“超出此世界”的明显写入速度,即使正确使用fsync也是如此。为避免这种可能性,请写随机数据。

1 几十MB的旋转磁盘上的缓存很常见,但这在SSD上不太常见。