【问题标题】:How do I minimize the amount of memory needed for a fixed allocation scheme?如何最小化固定分配方案所需的内存量?
【发布时间】:2013-06-18 10:30:23
【问题描述】:

下图可视化了 16 个不同大小的内存块所需的寿命:

我实际上要寻找的是许多 N 个大小为 sizei 的块em> 和生命周期 [begini, endi),返回最小大小的总内存块需要在我们的总时间间隔和 N 个偏移量中包含它们,offseti,进入输入块的总内存块。

一个简单的非最优算法如下:

int offsets[N];
offsets[0] = 0;
int total_size = size[0];
for (int i = 1; i < N; ++i)
{
    offsets[i] = offsets[i - 1] + size[i - 1];
    total_size += size[i];
}

我们当前的算法是按大小对块进行排序,然后从大到小处理它们,找到该块不与已“分配”的块重叠的第一个偏移量。这本质上是一个贪心算法,所以我感觉可以做得更好。

该算法只需要在应用程序启动时运行一次,因此它不必非常快。分配的数量大约为 10-50,对于我们的目的,时间可以离散为大约 50 个固定大小的单位。

【问题讨论】:

  • 这是一个非常模糊的提示,但不是绕着贪婪算法作弊的规范方法,尝试几种可能的解决方案,在这些解决方案中引入随机性或其他与直接方法的偏差,看看你是否得到改善? (例如成对交换 TSP 等)
  • (顺便说一句:您的可视化有点混乱,“使用的内存”不是更好吗?它可能会或可能不会让您发现间隙以及如何填充它们。“分配 ID " 似乎不是很重要。)
  • 您能详细说明一下吗? Allocation ID 基本上代表不同的对象,bar 代表它们在程序执行期间处于活动状态,非常重要。
  • 对,我现在意识到这是您的 输入 结构的可视化。所以我应该问的是你是否可以(另外)对你的贪婪算法提供的 output 进行可视化,其中一个轴是使用的内存(从 offset_i 开始的块offset_i+size),另一个是这里的时间。任何可见的差距可能提供关于如何重新安排以摆脱这种低效率的提示。 (或者,我承认这可能是一场野鹅追逐。)
  • 你的块大小是否也可以很好地离散化?在你的图中,它们看起来都是 265k 的小倍数。

标签: algorithm memory-management


【解决方案1】:

开始结束时间间隔列表中找出最短开始时间和最长结束时间。这是您感兴趣的时间的总间隔 (t_min, t_max)。接下来,将时间间隔划分为一些离散且均匀的间隔。设这个区间的长度为u。这基本上是您的内存管理的最大分辨率(您可以多久释放和/或申请一块内存)。

对于每个时间单位,确定哪些分配 ID 需要内存以及它们各自需要的大小,称之为 s(t, id)s(t, id) 在所有分配 ID 上的总和是您在任何给定时间需要多少总内存的下限。你不能做得比这个函数的最大值更好,它没有考虑到将事物分配在同一区域而不在每个时间步移动它们的愿望。

要为每个项目找到最佳位置,您可以使用启发式搜索。基本上,在每个内存块的所有可能起始地址的状态空间中搜索占用最小内存总量的解决方案,您可以通过模拟从 t_min 到 t_max 的时间进程来找到该解决方案。

一个可能值得尝试的启发式方法是更喜欢大块占用之前被其他大块占用的空间的分配,而小块被放置在对策略的最大内存使用贡献很小的位置。您还可以修剪任何比目前最好的策略更差的策略,因为该策略声称的最大内存随着时间的推移是单调的。

启发式搜索方法可能很慢,但听起来您更关心内存的最佳使用而不是分配算法的运行时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多