fwrite和写入大小的性能

我正在写一个大型数字二维数组到二进制文件(最终大小~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 ); .... 

如果我应该写下这些文字,那么每个文章应该有多大?

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

我同意miked和Jerome的大部分内容,但……仅适用于现代操作系统。 如果您正在嵌入闪存文件系统,则有一些主要的例外情况。 在这种环境中,如果您怀疑fwrite(),请使用带有大块的write()进行快速测试。

今天,我发现写入()的速度提高了4倍。 这是由于嵌入式操作系统中的posix层将fwrite()s转换为fputc()s …在这种情况下,SYNC’d底层闪存文件只会被破坏。 write()由更接近OS(Nucleus)的例程实现,其中块写入不会被分成字节。

只是说…如果你质疑这两个变种,可能最好只是尝试一下。

你可能会通过使用nmap()获得更高的性能,为你的数组创建空间(虚拟地址空间),然后写入’memory’而不是磁盘。

让系统为您完成:它可能会分配尽可能少的页面,这是由fwrite()转储的75 MB缓冲区不会发生的事情。

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

一块更快。 有几个原因:

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

2)磁盘I / O很慢,因此OS通常会尝试在其端实现一些缓存。 这意味着每次使用文件I / O时,如果它被缓存,将会有额外的检查,如果它应该被缓存,等等。

你可以找到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)直接写入将绕过这个额外的副本。