【问题标题】:Performance of fwrite and write sizefwrite 和写入大小的性能
【发布时间】:2011-05-20 01:03:31
【问题描述】:

我正在将一个大型数字二维数组写入二进制文件(最终大小约为 75 MB)。

我在 linux 系统上执行此操作。首先,除了 fwrite 之外,还有没有更好的方法或系统调用来尽可能快地写入文件?

其次,如果我应该使用 fwrite,那么我应该将整个文件写为 1 个连续的行吗?

fwrite( buf, sizeof(float), 6700*6700, fp );

或者把它写成一系列的块

fwrite( buf, sizeof(float), 8192, fp );
fwrite( *(buf+8192), sizeof(float), 8192, fp );
....

如果我应该分块写作,每个块应该有多大?

【问题讨论】:

    标签: c performance file-io


    【解决方案1】:

    我在很大程度上同意 miked 和 Jerome 的观点,但……仅适用于现代操作系统。如果您在 Flash 文件系统上进行嵌入工作,则有一些主要的例外情况。在这种环境下,如果您怀疑 fwrite(),请使用带有大块的 write() 进行快速测试。

    今天,我发现转向 write() 的速度提高了 4 倍。这是由于嵌入式操作系统中的一个 posix 层将 fwrite()s 转录为 fputc()s ......在这种情况下,一个 SYNC 的底层闪存文件只是垃圾。 write() 是由更接近于 OS (Nucleus) 的例程实现的,在该例程中,块写入不会被分解为字节。

    只是说...如果您对这两个变体有疑问,最好尝试一下。

    【讨论】:

      【解决方案2】:

      只需使用 fwrite(无需进入较低级别的系统调用)并将其作为一个块来执行。较低级别的系统调用将弄清楚如何最好地缓冲和拆分该写入命令。我从来没有能够在像这样的事情上击败 fwrite 的性能 - 大型顺序写入。

      【讨论】:

      • 我同意。我见过的唯一比标准 fwrite() 到文件表现更好的是 fwrite() 到 /dev/shm 上的文件:-)
      【解决方案3】:

      您可能会通过使用 nmap() 获得更高的性能,为您的阵列(虚拟地址空间)创建空间,然后写入“内存”而不是磁盘。

      让系统为你做这件事:它可能会分配尽可能少的页面,而 fwrite() 转储的 75 MB 缓冲区不会发生这种情况。

      在 CPU 缓存受限的世界中,使用巨大的缓冲区是行不通的(这就是 malloc() 使用 nmap() 进行大分配的原因)。通过在设置 nmap() 时将缓冲区附加到文件 - 在填充缓冲区之前,您将为系统节省大量工作。

      【讨论】:

      • 叫做 mmap()
      【解决方案4】:

      一个块更快。有几个原因:

      1) 写入 HDD 还意味着保持“最新”文件系统中的所有附加信息(时间戳、文件大小、使用的集群、锁等),因此每次文件访问都会产生一些开销(尤其是写权限)。

      2) 磁盘 I/O 很慢,因此操作系统通常会尝试在其一侧实现一些缓存。这意味着每次使用文件 I/O 时,都会额外检查它是否被缓存,是否应该被缓存,等等。

      【讨论】:

        【解决方案5】:

        你可以在里面找到fwrite的源码

        http://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iofwrite.c;hb=HEAD

        如你所见,这反过来又调用了 IO_sputn,最终在

        http://sourceware.org/git/?p=glibc.git;a=blob;f=libio/fileops.c;hb=HEAD

        (特别是 _IO_new_file_xsputn)。如您所见,这总是通过 stdio 缓冲区。

        所以我建议不要使用 stdio;使用 write(2) 直接写入将绕过这个额外的副本。

        【讨论】:

        • 或者使用 glibc 提交错误报告。当数据大于缓冲区时,通过缓冲区写入是荒谬的。
        • 5 年后这仍然是真的吗?
        猜你喜欢
        • 2012-05-20
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-28
        • 1970-01-01
        相关资源
        最近更新 更多