假设我有一个数据集,它是存储在 4TB HDD ext4 文件系统上的文件中的 1e12 32 位整数 (4 TB) 数组。
考虑到数据很可能是随机的(或者至少看起来是随机的)。
// 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 更好的性能?
一方面,您广泛使用内存交换导致轻微的页面错误,对于应用程序来说是透明的。另一方面,你有无数系统调用,具有已知的开销。维基百科页面关于内存映射文件 http://en.wikipedia.org/wiki/Memory-mapped_file对我来说似乎很清楚,它全面地浏览了优点和缺点。
我认为 64 位架构 + 大文件需要内存映射文件方法,至少可以避免应用程序变得复杂;有人告诉我,复杂性往往会导致性能不佳。然而mmap()
通常用于顺序访问,但这不是这里的目的。
因为这是纯随机访问,所以两次访问出现在同一个 RAM 加载页面中的可能性很小。一个完整的 4kb 页将从 HDD 交换到 RAM,只是为了 4 字节数据...这对总线来说是无用的加载,并且可能会导致性能不佳。
希望这有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)