【问题标题】:Algorithm for covering memory ranges?覆盖内存范围的算法?
【发布时间】:2012-09-24 15:44:49
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: algorithm memory


    【解决方案1】:

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

    我们需要覆盖一组范围,总长度为 M,最多 N 页面可能有L个不同的长度,它们没有对齐(可以放置在任何地址)。 pages 的总“额外”区域和总长度之间的差异等于常数 M,这允许最小化 pages 的总长度。

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

    1. 页面以某个未占用的位置结束。边到顶点,对应这个位置后第一个范围的起始地址。
    2. 页面在某个范围内结束。边到顶点,对应页面的结束地址。
    3. 页面以未占用位置结束,其地址大于任何范围的地址。边缘到达 destination 顶点。 (第一个range的起始地址对应source顶点,我们应该找到这两个顶点之间的最短路径。

    由于结果图是DAG,因此可以通过按拓扑顺序(或者更简单,按相应内存地址的顺序)处理顶点,在线性时间内找到最短路径。

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

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

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

    【讨论】:

      【解决方案2】:

      自下而上的贪心方法,当每个长度都是最后一个的倍数时有效:

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

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

      【讨论】:

        【解决方案3】:

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

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

        1) 用从“范围”的最小值到最大值的大间隔覆盖它们。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-18
          • 2014-02-04
          • 2014-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多