我正在使用 mmap/read + BZ2_bzDecompress 顺序解压缩一个大文件(29GB)。这样做是因为我需要解析未压缩的 xml 数据,但只需要它的一小部分,而且似乎顺序执行此操作比解压缩整个文件(未压缩 400GB)然后解析它更有效。有趣的是,解压部分已经非常慢了——虽然 shell 命令 bzip2 每秒能够执行超过 52MB 的速度(使用了几次运行timeout 10 bzip2 -c -k -d input.bz2 > output
并将生成的文件大小除以 10),但我的程序甚至不能达到 2MB/s,几秒钟后减速至 1.2MB/s
我正在尝试处理的文件使用多个 bz2 流,因此我正在检查BZ2_bzDecompress
,BZ_STREAM_END
如果它发生,请使用BZ2_bzDecompressEnd( strm );
并BZ2_bzDecompressInit( strm, 0, 0 )
重新启动下一个流,以防文件尚未完全处理。我也试过没有BZ2_bzDecompressEnd
,但这并没有改变任何东西(而且我在文档中看不到应该如何正确处理多个流)
该文件之前被 mmap'ed,我还尝试了不同的标志组合,目前MAP_RDONLY
,MAP_PRIVATE
使用 madvise to MADV_SEQUENTIAL | MADV_WILLNEED | MADV_HUGEPAGE
(我正在检查返回值,并且 madvise 没有报告任何问题,并且我使用的是 linux 内核 3.2x debian具有大页面支持的设置)
在分析时,我确保除了一些用于测量速度的计数器和一个限制为每 n 次迭代一次的 printf 之外,没有运行其他任何东西。这也是在现代多核服务器处理器上,所有其他内核都处于空闲状态,并且是裸机,未虚拟化。
关于我可能做错什么/做什么来提高性能的任何想法?
更新:感谢 James Chong 的建议,我尝试“交换” mmap()
,read()
速度还是一样的。所以这似乎mmap()
不是问题(要么,要么mmap()
共享read()
一个潜在的问题)
更新 2:认为可能是在 bzDecompressInit/bzDecompressEnd 中完成的 malloc/free 调用是原因,我将 bz_stream 结构的 bzalloc/bzfree 设置为一个自定义实现,该实现只在第一次分配内存并且除非标志是设置(由 opaque 参数 = strm.opaque 传递)。它工作得很好,但速度再次没有增加。
更新 3:我现在也尝试了 fread() 而不是 read(),但速度仍然保持不变。还尝试了不同数量的读取字节和解压缩数据缓冲区大小 - 没有变化。
更新 4:读取速度绝对不是问题,因为我已经能够在仅使用 mmap() 的顺序读取中实现接近 120MB/s 的速度。