fwrite对于大量小写的效率

cam*_*ccc 7 c++ unix fwrite system-calls

我有一个程序可以保存许多大文件> 1GB使用fwrite它工作正常,但不幸的是由于数据的性质每次调用fwrite只写1-4字节.结果是写入可能需要一个多小时,大部分时间似乎是由于系统调用开销(或至少在fwrite的库函数中).我有类似的问题fread.

有没有人知道任何现有/库函数将使用内联函数缓冲这些写入和读取,或者这是另一个自己的卷?

NPE*_*NPE 14

首先,fwrite()是一个库而不是系统调用.其次,它已经缓冲了数据.

您可能希望尝试增加缓冲区的大小.这是通过使用完成的setvbuf().在我的系统上,这只有一点点帮助,但是YMMV.

如果setvbuf()没有帮助,你可以自己做缓冲,只有fwrite()在你积累了足够的数据后才能打电话.这涉及更多的工作,但几乎肯定会加快写作速度,因为你自己的缓冲可以变得更加轻巧fwrite().

编辑:如果有人告诉你这fwrite()是问题的绝对数量,请求查看证据.更好的是,做自己的性能测试.在我的计算机上,500,000,000个双字节写入使用fwrite()需要11秒.这相当于大约90MB/s的吞吐量.

最后但并非最不重要的是,我的测试中的11秒与您的问题中提到的一小时之间的巨大差异暗示了您的代码中可能存在导致性能非常差的其他因素的可能性.

  • @Skizz:是什么让你这么想的?如果你有任何证据,我很乐意看到它. (3认同)
  • 我同意NPE.fwrite不是系统调用!! 多次调用它是免费的.人们说相反需要回到学校.您可以设置一个大的enougth缓冲区来减少底层系统调用,这就是"write(fd,void*,int)"函数. (3认同)

len*_*nik 5

你的问题不是缓冲fwrite(),而是用少量数据调用库的总开销.如果只写1MB数据,则可以进行250000次函数调用.您最好尝试在内存中收集数据,然后通过一次调用写入磁盘fwrite().

更新:如果您需要证据:

$ dd if=/dev/zero of=/dev/null count=50000000 bs=2
50000000+0 records in
50000000+0 records out
100000000 bytes (100 MB) copied, 55.3583 s, 1.8 MB/s
$ dd if=/dev/zero of=/dev/null count=50 bs=2000000
50+0 records in
50+0 records out
100000000 bytes (100 MB) copied, 0.0122651 s, 8.2 GB/s
Run Code Online (Sandbox Code Playgroud)

  • 这个答案具有很强的误导性。dd with bs=2 实际上会每两个字节向内核发出一次 write 系统调用。启用默认缓冲的 fwrite 将每两个字节调用一次本地库函数,然后每次缓冲区满时调用一次写入系统调用。主要开销是内核调用,因此 dd bs=2 并不是对 2 字节块的 fwrite 的准确模拟。 (2认同)

Eug*_*sev 1

如果您仅从一个线程写入,请尝试使用fwrite_unlocked. fwrite在这种情况下,它相对于直线确实有奇迹。