Linux:大型int数组:mmap vs查找文件?

假设我有一个数据集,它是一个存储在4TB HDD ext4文件系统文件中的1e12 32位整数(4 TB)数组。

考虑到数据很可能是随机的(或者至less似乎是随机的)。

// pseudo-code for (long long i = 0; i < (1LL << 40); i++) SetFileIntAt(i) = GetRandInt(); 

此外,考虑我希望以不可预知的顺序读取单个int元素,并且algorithm运行不确定(正在进行)。

 // pseudo-code while (true) UseInt(GetFileInt(GetRand(1<<40))); 

我们在Linux x86_64上,gcc。 您可以假设系统具有4GB的RAM(即比数据集小1000倍)

以下是架构访问的两种方法:

(A)将文件映射到4TB的内存块,并以int数组的forms访问它

(B)打开(2)文件并使用seek(2)和read(2)来读取整数。

A和B哪个会有更好的performance?为什么?

还有另一种devise能比A或B提供更好的性能吗?

Solutions Collecting From Web of "Linux:大型int数组:mmap vs查找文件?"

如果访问是真正随机的,我会说性能应该是相似的。 操作系统将使用类似的缓存策略,无论数据页面是从文件映射的,还是文件数据只是缓存而没有与RAM的关联。

假设缓存无效:

  • 您可以使用fadvise预先声明您的访问模式并禁用预读。
  • 由于地址空间布局随机化,在虚拟地址空间中可能不会有连续4TB的块。
  • 如果您的数据集扩展,地址空间问题可能会变得更加紧迫。

所以我会去显式读取。

一方面,你大量使用内存交换,导致较小的页面错误 ,对应用程序是透明的。 另一方面,你有许多系统调用 ,已知的开销。 关于内存映射文件的维基百科页面似乎对我来说很清楚,它综合浏览的优点和缺点。

我认为64位体系结构+大文件调用内存映射文件的方法,至少不要复杂的应用程序; 我被告知,复杂性往往导致表现不佳。 然而, mmap()通常是顺序访问,这不是目的。

因为这是纯粹的随机访问,所以两次访问将在同一个RAM加载的页面中的几率很小。 一个完整的4kb的页面将被从硬盘交换到RAM,只是为了一个4字节的数据…这是无用的总线加载,可能会导致糟糕的表现。

希望这个帮助。

可能对于4TB线性数据集,您不需要文件系统。 我猜想原始设备访问可能会带来一些性能优势。

也可能有一种方法来优化查询或数据结构,以便更有效地使用缓存?

寻求性能高度取决于你的文件系统的实现。 Ext4应该是一个很好的选择,因为它使用扩展树 。 此外,如果您的文件具有线性连续分配,则范围树将由单个条目组成,这使得查找效率更高。