覆盖内存范围的算法?

时间:2012-09-24 15:44:50

标签: algorithm memory

我有一组范围,例如{(2-8),(13-22),(380-7931),(40032-63278)}。为简单起见,我们可以假设它们不重叠(重叠范围已经合并)。

我的目标是使用一组给定的“长度”组合来“覆盖”这些范围,例如{4,64,1024,16384}。我被限制使用最多N个长度,例如N = 32。我不在乎我使用多少“长度”,只要我低于我的最大值,但我想最小化总“额外”区域 - 数字“覆盖”长度不在初始范围集中。

由(2-66)覆盖的示例{(2-8)}(使用64的一个长度)具有58个“额外”数字。 {(2-8)}覆盖{(2-6),(6-10)}(两个长度为4)只有2个“额外”数字,是优选的。

我的真实世界应用涉及对固定MMU TLB进行预编程,以确保只能访问某些范围的存储器地址(TLB未命中因此代表禁止访问,并且可以相应地处理)。我想尽可能紧密地覆盖范围,以便尽早发现违规行为,但我只有32个插槽可供使用,4个固定页面大小。我可以手动调整我的代码到足够的性能水平,但我很好奇是否有更优雅/通用的解决方案。这似乎与背包问题有关,但不同的是它很难搜索。

3 个答案:

答案 0 :(得分:1)

这可以表示为Shortest path problem的变体。

我们需要涵盖一组总长 M 范围,最多 N 页面页面可能具有 L 不同的长度,它们未对齐(可以放置在任何地址)。总“额外”区域与页面总长度之间的差异等于常量 M ,这样可以最小化页面的总长度。 / p>

让我们构建一个与此问题相关的图表。任何范围中的每个内存地址都在图中具有相应的顶点。从给定地址开始,每个顶点都有 L 传出边,对应 L 。每条边的长度等于 page 长度。每个边都到达图中的某个顶点,具体取决于相应的 page 结束的位置:

  1. Page 以某种无人居住的姿势结束。 Edge到达顶点,对应于此位置后第一个范围的起始地址。
  2. Page 范围内结束。 Edge到达顶点,对应于页面的结束地址。
  3. Page 以无人居住的位置结束,地址大于任何范围的地址。 Edge来到目的地顶点。 (第一个范围的起始地址对应于 source 顶点,我们应该找到这两个顶点之间的最短路径。)
  4. 由于结果图是DAG,因此可以通过以拓扑顺序处理顶点(或者更简单地按照相应的存储器地址的顺序)在线性时间中找到最短路径。

    对于每个顶点,保留一个 N 对的数组{path-length,back-pointer}。当最短路径算法访问任何顶点时,使用路径中的跳数索引此数组,如果路径短于存储的路径长度,则替换{path-length,back-pointer}。处理每个顶点时,找到属于 destination 顶点的对数组中的最短路径,然后使用反向指针重建路径。此路径描述了最佳封面。

    最坏情况时间复杂度O(L * M * N)由属于每个顶点(N)的最大边数(L * M)和数组中的元素数确定。如果范围是稀疏的,则大多数边缘到达某些范围的起始地址,大多数顶点,对应于内部地址未使用,时间复杂度要小得多。

    此算法需要O(M * N)空间,但对于稀疏范围,如果我们将所有图形顶点(或者可能是所有长度/指针对)放入哈希映射中,这可能会显着减少

答案 1 :(得分:0)

考虑您想要覆盖的范围是非常低值的区间(让我们称之为“范围”),并且间隙(称之为“额外”)是非常昂贵的区间。现在我们希望以最多N个间隔(称为“覆盖”)最小化总成本,其覆盖所有“范围”并且可能包含一些“额外”。 以下算法本质上是贪婪的。

首先考虑你想要覆盖的所有间隔(“范围”)以及它们之间的“额外”。

1)从“范围”的最小值到最大值间隔很长的间隔。

2)迭代并删除之间最昂贵的“额外”(即最大跨度) 并且将该divison视为创建一个额外的“封面”,直到封面的数量变为N或者您用完了昂贵的“额外”。

答案 2 :(得分:0)

自下而上的贪婪方法,当每个长度是最后一个的倍数时起作用:

从一组最小长度间隔开始,最小限度地覆盖所有范围。迭代合并最长的运行,直到低于最大范围计数。

在你的情况下,在TLB上,你可能有对齐约束,这会使问题变得有点棘手。