7

在 Linux 64 位(例如 Amazon EC2 实例)上,我需要将几个大型二进制文件加载到内存中。最快的方法是什么?

  • 恐惧
  • POSIX 开放
  • POSIX mmap(实际上并未将整个文件加载到内存中,这会损害性能)
  • 别的东西?

此外,节点可能会或可能不会再次启动此可执行文件,因此如果文件在后续尝试中加载得更快,这将有所帮助。某种预加载步骤甚至可能起作用。

4

3 回答 3

6

时间将由磁盘 I/O 主导,因此您使用哪种 API 不如考虑磁盘如何工作重要。如果您随机访问磁盘(旋转媒体),则查找将花费 3 到 9 毫秒……一旦磁盘开始流式传输,它可以维持大约 128 MB/秒,这就是磁盘磁头的速度有多快。SATA 链接或 PCIe 总线的带宽比这高得多(600 到 2000 MB/秒)。Linux 在内存中有一个页面缓存,它在磁盘上保存页面的副本,因此只要您的机器有足够的 RAM,即使您随后随机访问数据,后续尝试也会很快。所以建议是一次读取大块。如果你真的想加快初始加载速度,那么你可以使用 mmap 来映射整个文件(1GB-4GB),并有一个帮助线程按顺序读取每个页面的第一个字节。

您可以在此处阅读有关磁盘驱动器性能特征的更多信息。

您可以在此处阅读有关页面缓存的更多信息。

于 2013-02-11T22:46:10.613 回答
0

鉴于上述信息,我会说mmap是一个很好的候选人。我这么说有几个原因: 1. 它为您提供整个文件,而无需实际加载(任何)文件,直到实际需要该部分。这是快速加载的一个优势,但如果您最终会遍历每个字节[或触及文件的每个 4KB 部分],那么没有太大区别。2.mmap只会将数据从磁盘复制一次到您的页面。这在我的测试中比使用freadread在 Linux 中读取更有效(另请注意,可以忽略相当大的读取之间的差异。freadreadFILEC 中的函数。C++ 流增加了相当多的开销,但是,根据我的经验 [我现在已经尝试了很多次这种形式的各种形式]。

像往常一样,基准测试总是胜过互联网上的询问。所以你可能会发现我上面所说的在你的情况下是不正确的。正如所指出的,一旦代码足够好,代码中的任何开销都会与磁盘传输数据的速度相形见绌——即使你有一个非常漂亮的 RAID 系统,最终有很多并行(SSD?)磁盘等磁盘传输速度将成为瓶颈所在。此时您所能做的就是尽量减少其他开销,并在磁盘交付数据后尽快将数据发送到应用程序。

“每秒字节数”的一个很好的基准是使用dd if=/dev/zero of=somefile bs=4K count=1M(写入文件,然后您可能想dd if=somefile of=/dev/null bs=4K看看您可以从磁盘读取多少。

于 2013-02-11T23:39:44.997 回答
0

你可以试试mmapflag MAP_POPULATE。我怀疑你可以更快地做到这一点。

于 2013-02-15T03:37:29.243 回答