我正在开发一个程序,该程序将处理大小可能为 100GB 或更大的文件。这些文件包含可变长度记录集。我已经启动并运行了第一个实现,现在正在寻求提高性能,特别是在更有效地执行 I/O 方面,因为输入文件被扫描了很多次。
mmap()通过 C++ 的库在块中使用与读取是否有经验法则fstream?我想做的是将大块从磁盘读取到缓冲区中,处理缓冲区中的完整记录,然后读取更多。
mmap()
fstream
mmap()代码可能会变得非常混乱,因为’ mmapd 块需要位于页面大小的边界上(我的理解),并且记录可能会跨越页面边界。使用fstreams,我可以寻找记录的开头并再次开始阅读,因为我们不限于阅读位于页面大小边界上的块。
mmap
在没有实际编写完整实现的情况下,如何在这两个选项之间做出决定?任何经验法则(例如,mmap()快 2 倍)或简单测试?
我试图找到关于 Linux 上 mmap / 读取性能的最终决定,我在 Linux 内核邮件列表上发现了一篇不错的帖子(链接)。它是从 2000 年开始的,因此从那时起内核中的 IO 和虚拟内存有了很多改进,但它很好地解释了为什么mmap或者read可能更快或更慢的原因。
read
epoll
poll
然而,
mlock
mmap/read 的讨论让我想起另外两个性能讨论:
一些 Java 程序员震惊地发现非阻塞 I/O 通常比阻塞 I/O 慢,如果您知道非阻塞 I/O 需要进行更多的系统调用,这完全有道理。
其他一些网络程序员惊讶地发现它epoll通常比.poll``epoll
poll``epoll
结论: 如果您随机访问数据,将其保存很长时间,或者如果您知道可以与其他进程共享它(MAP_SHARED如果没有实际共享,则不是很有趣),请使用内存映射。如果您按顺序访问数据或在读取后将其丢弃,则可以正常读取文件。如果任何一种方法都可以让你的程序变得不那么复杂, 那就 这样做吧。对于许多现实世界的案例,如果不测试您的实际应用程序而不是基准测试,就无法确定一种方法会更快。
MAP_SHARED
(对不起,这个问题被删除了,但我一直在寻找答案,这个问题一直出现在谷歌搜索结果的顶部。)