假设我的数据集是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更好的性能?
答案 0 :(得分:3)
一方面,您广泛使用内存交换,导致次要页面故障,对应用程序而言是透明的。另一方面,您有许多系统调用,具有已知的开销。关于memory-mapped file的维基百科页面似乎对我来说非常清楚,它以全面的方式浏览利弊。
我认为64位架构+大文件调用内存映射文件的方法,至少要避免复杂化应用程序;有人告诉我,复杂性通常会导致性能不佳。但是mmap()
通常用于顺序访问,这不是目的。
因为这是纯随机访问,所以两次访问在同一个RAM加载页面中的可能性很小。一个完整的4kb页面将从HDD交换到RAM,仅用于4字节数据......这是无用的总线加载,可能会导致性能不佳。
希望得到这个帮助。
答案 1 :(得分:1)
如果访问真的是随机的,我会说性能应该相似。操作系统将使用类似的缓存策略,无论数据页是从文件映射还是文件数据只是缓存而没有与RAM的关联。
假设缓存无效:
fadvise
提前声明访问模式并禁用预读。所以我选择明确的读物。
答案 2 :(得分:1)
对于4TB线性数据集,您可能不需要文件系统。我想原始设备访问可能会带来一些性能优势。
也可能有一种优化查询或数据结构的方法,以便更有效地使用缓存?
答案 3 :(得分:1)
高性能的搜索取决于您的文件系统实现。 Ext4应该是一个很好的选择,因为它使用extent trees。此外,如果您的文件具有线性连续分配,则范围树将由单个条目组成,这使得搜索非常有效。