algorithm - 大型数据集的高效重新排序以最大化内存缓存效率

标签 algorithm caching graph-theory ram

我一直在研究一个我认为人们可能会感兴趣的问题(也许有人知道一个预先存在的解决方案)。

我有一个大型数据集,其中包含一长串指向对象的指针对,如下所示:

[
  (a8576, b3295), 
  (a7856, b2365), 
  (a3566, b5464),
  ...
]

在任何时候都有太多的对象无法保存在内存中(可能有数百 GB),因此它们需要存储在磁盘上,但可以缓存在内存中(可能使用 LRU 缓存)。

我需要遍历这个列表来处理每一对,这需要将这对中的两个对象都加载到内存中(如果它们还没有缓存在那里)。

因此,问题是:是否有一种方法可以重新排列列表中的对,以最大限度地提高内存缓存的有效性(换句话说:最大限度地减少缓存未命中的次数)?

注意事项

  1. 显然,重新排序算法应该尽可能快,并且不应该依赖于能够一次将整个列表存储在内存中(因为我们没有足够的 RAM)-但如有必要,它可以多次遍历列表。

  2. 如果我们处理的是单个对象,而不是成对对象,那么简单的答案就是对它们进行排序。这在这种情况下显然行不通,因为您需要考虑这对中的两个元素。

  3. 问题可能与寻找minimum graph cut 的问题有关。 , 但即使问题是等价的,我也不认为 min-cut 的解决方案满足

  4. 我的假设是,启发式算法会将数据流出磁盘,然后以更好的顺序将其写回 block 中。它可能需要对此进行多次迭代。

  5. 实际上它可能不仅仅是一对,它可能是三胞胎、四胞胎或更多。我希望为对执行此操作的算法可以很容易地推广。

最佳答案

您的问题与计算机图形硬件的类似问题有关:

在三角形网格中渲染索引顶点时,通常硬件有一个最近变换顶点的缓存(上次我不得不担心它时大约有 128 个,但怀疑这些天这个数字更大)。未缓存的顶点需要相对昂贵的变换操作来计算。重构三角形网格以优化缓存使用的“网格优化”曾经是一个非常热门的研究课题。谷歌搜索 顶点缓存优化 (或优化 :^)可能会为您找到一些与您的问题相关的有趣 Material 。正如其他张贴者所建议的那样,我怀疑有效地做到这一点将取决于利用数据中的任何内在连贯性。

另一件要记住的事情:当 LRU 缓存变得过载时,很值得更改为 MRU 替换策略以至少将一些项目保留在内存中(而不是每次通过都翻转整个缓存)。我似乎记得 John Carmack 在与 Direct3D 纹理缓存策略相关的这个主题上写了一些很好的 Material 。

关于algorithm - 大型数据集的高效重新排序以最大化内存缓存效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/499562/

相关文章:

linux - 在 Linux 用户空间应用程序中启用写入组合?

android - 如何在 Android 中创建带有边和顶点的图

algorithm - 图问题松弛二分维简例的快速逼近

algorithm - 在机器学习中使用图论的建议?

ios - 预填充 RestKit 缓存

java - 一个对象的JVM深内存大小

python - 计算 GCD - 如何检查列表中的每个元素

algorithm - 给定共同的宽度和 3 个点,求 3 个矩形的长度,使它们共享一个角以形成一个三角形

python - 计算 Python 字符串中连续重复字母的实例

arrays - 在不到 O(n) 的时间内反转数组的子数组