【问题标题】:Best way to save a large binary file by chunks asynchronously in C++在 C++ 中通过块异步保存大型二进制文件的最佳方法
【发布时间】:2021-07-06 03:40:57
【问题描述】:

我正在开发一个 C++ 应用程序,它的输出是一个大的二进制文件(几 GB,基本上是一个大的浮点序列)。该文件的内容是由并行进程异步生成的。

每次进程完成时,它的结果必须保存到磁盘中二进制文件内的相应位置(进程完成的顺序不一定与它们的结果存储在磁盘。大约需要 5 个进程才能获得输出的完整数据)。

在 C++ 中实现这一目标的最佳方法是什么?我有几个可行的解决方案,但也许可以在最小化磁盘使用方面进行改进:

  • 为每个完成的进程保存单独的文件,然后合并
  • 保持 fstream 打开并使用 seekp() 为每个保存操作定位 put 指针

【问题讨论】:

  • 几 GB 的文件?为什么不先将其存储在 RAM 中;一个大的std::vector<float>。填好后,生成文件。
  • 如果合并文件很简单,那么这可能就是要走的路。否则,您需要担心同步问题。
  • 您是提前知道最终文件中的确切位置,还是在所有过程完成后确定它们?块是否与某个边界对齐?
  • 提前知道最终文件中的确切位置,以及文件的最终大小
  • 这是特定于操作系统和文件系统的。我的建议(如果在 Linux 上)是生成十几个较小的文件(例如每个 100Mbytes)或考虑使用 sqlitePostGreSQL... 不要忘记备份输出(远程或在外部媒体上)

标签: c++ asynchronous parallel-processing fstream disk-io


【解决方案1】:

如果可以避免的话,我不建议将时间浪费在写入临时文件和合并上。

序列化到单个进程/单个流可能会快得多。但请确保在至少 64 KB 的某些块中进行查找和写入,以减少开销。

我根本不会使用 fstream,因为它们会带来一些开销(并且您依赖于实现的质量,这在 1234 中很明显)。最好只使用fopen,禁用缓冲,然后写入 64 KB+ 的块。

为了获得更好的性能,可以使用内存映射 I/O,例如使用 Boost.Iostreams (example)。您也可以从多个进程进行内存映射。

如果单独进程生成的片段是 4 KB 或更大的倍数,在大多数操作系统上,您可以简单地在每个进程中打开相同的文件,寻找所需的位置并写入(不是很便携,但在 Linux、BSD 上可以和 Win32)。在 Win32 上只需要相应地设置文件共享模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2016-09-11
    • 2019-10-02
    • 2010-10-14
    • 2021-06-21
    相关资源
    最近更新 更多