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

时间:2012-06-14 07:24:05

标签: linux memory memory-management filesystems x86-64

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

考虑数据最有可能是随机的(或者至少是随机的)。

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

此外,考虑到我希望以不可预测的顺序读取单个int元素,并且该算法运行不确定(它正在进行中)。

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

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

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

(A)将文件mmap到4TB内存块,并将其作为int数组访问

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

A和B会有更好的表现吗?为什么?

是否有其他设计可以提供比A或B更好的性能?

4 个答案:

答案 0 :(得分:3)

一方面,您广泛使用内存交换,导致次要页面故障,对应用程序而言是透明的。另一方面,您有许多系统调用,具有已知的开销。关于memory-mapped file的维基百科页面似乎对我来说非常清楚,它以全面的方式浏览利弊。

我认为64位架构+大文件调用内存映射文件的方法,至少要避免复杂化应用程序;有人告诉我,复杂性通常会导致性能不佳。但是mmap()通常用于顺序访问,这不是目的。

因为这是纯随机访问,所以两次访问在同一个RAM加载页面中的可能性很小。一个完整的4kb页面将从HDD交换到RAM,仅用于4字节数据......这是无用的总线加载,可能会导致性能不佳。

希望得到这个帮助。

答案 1 :(得分:1)

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

假设缓存无效:

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

所以我选择明确的读物。

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

高性能的搜索取决于您的文件系统实现。 Ext4应该是一个很好的选择,因为它使用extent trees。此外,如果您的文件具有线性连续分配,则范围树将由单个条目组成,这使得搜索非常有效。