文件 I/O 性能好得令人难以置信?

chu*_*9ri 3 c io performance file

我运行了一个简单的文件 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;
}
Run Code Online (Sandbox Code Playgroud)

Bee*_*ope 5

操作系统通常将写入内容缓存在 RAM 中,并仅在通常以秒为单位的一段时间后将其写出(取决于确切的操作系统配置)。除此之外,甚至您的磁盘驱动器也可能有 RAM 缓存1

如果您写入足够的数据(例如,超过您拥有的 RAM 量),您会在某个时刻看到速度急剧下降,因为操作系统现在必须同步写出文件数据,以便为新写入腾出空间。

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

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

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


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

  • 此外,驱动器也将进行自己的缓存。如果它是日志文件系统,则“写入文件”会在稍后将日志刷新到正确的文件系统中。一切都非常复杂! (2认同)