如何评估自定义内存分配器的质量?

时间:2013-04-19 07:38:22

标签: c++ c testing memory-management

评估内存分配时应检查哪些特性?

分配和取消分配的表现?简单的压力测试足够吗?如何检查分配质量?

例如,我发现了Oracle对malloc的测试,但这只是Oracle对该问题的看法。此测试仅面向多线程性能。

人们通常如何检查他们的分配器?

4 个答案:

答案 0 :(得分:4)

只是为了更多地关注“如何”,而不是其他答案似乎要处理的“什么”。我就是这样做的。

第一步 - 可以比较方法

确定您重视的品质。制作一个列表,确定优先级,最后创建一个值函数。

也就是说,在您的视图/案例中,确定哪些测量是最有用的质量指标。一些好的测量可能是分配内存块的平均时间,应用程序的总运行时间(如果适用),平均帧速率,总内存消耗或平均内存消耗......这一切都取决于您希望实现的目标。

然后,创建一个函数,根据测试运行中的这些测量结果,给出一个可用作质量测量值的函数。最简单的情况是简单地确定每个测量的权重因子。这些权重因子应该体现每个测量的重要性,如果它们使用不同的单位(例如平均分配时间的纳秒和平均内存消耗的字节),则尝试将它们进行比较以进行公平比较。

第二步 - 设置测试场景

这应该尽可能接近现实案例。最好的只是您想要使用内存分配器的实际代码,并添加了用于计算您的值函数所需的所有测量的代码。

第三步 - 测试

编写一堆不同的分配器并相互测试它们,以及默认或没有任何分配器(如果适用)。测量所有结果,计算每个结果的值函数,并根据结果对它们进行排序。请记住在执行性能测量时始终需要考虑的所有不同注意事项。

第四步 - 评估并重新

看看不同的解决方案如何相互叠加。运用一些批判性思维。这些结果是否实际上与您在测试期间体验每个分配器的质量相对应?如果结果与您所看到的不符。

例如,如果一个看起来速度极快并且总运行时间比其余部分少半分钟的那个,那就得到一个平庸的分数。那么,是时候仔细检查你的方法了。也许你的测量中有一个错误?或者您可能需要重新评估您选择的值函数...重复步骤1到4,直到结果清晰,并且看起来与您测试它们的实际经验相符。

答案 1 :(得分:2)

通常,内存分配器的性能取决于查找的速度,并根据被操作的内存块的大小在堆中创建内存块。并且,(但最近),它在多线程分配的情况下如何表现。您可以在以下列表中找到有趣的研究和基准:

答案 2 :(得分:1)

我想我的回答不是天才,而是 - 这取决于。

如果您正在编写自定义内存分配器,您可能知道它的特性应该是什么。例如。如果你想让分配器允许你快速分配很多小对象并且你真的不关心内存使用开销你应该有不同的测试然后当你为大对象创建分配器并且你想要节省尽可能多的内存即使占用CPU时间也是可能的。

压力测试总是很好,因为它可以帮助你找到一些竞争条件并检查你的分配器是否是无错误的,但是灌注测试取决于你想要实现的目标。

答案 3 :(得分:1)

以下是在优化/分析系统中动态内存分配机制时应考虑的指标。

  • 实施开销-保持分配的内部数据结构正常运行需要花费多少内存。此外,如果这些结构随着时间的推移而增长或预先分配一次(两种方法各有利弊,并且两者都是有效的)。
  • 操作效率-分配/释放内存块需要多长时间。在这里,分配通常是一个挑战,因为它几乎永远不是恒定的时间,并且取决于先前分配的内存块的特性。释放块看起来很简单,但是如果与内存碎片整理结合使用,则值得进一步关注(此处将不介绍)。
  • 线程安全性与分配本身无关,而与在系统中使用某些解决方案的决定有关。基本上在这里,如果您没有线程-无需担心。如果您有线程,请确保工作时不会中断分配。
  • 内存碎片-分配的内存的实际布局。这里有两个完全矛盾的要求-您在缓冲区中找到正确的位置后立即进行分配,或者确保尽可能减少碎片。前者速度快,而后者则对资源更友好(并且还可能更慢)。
  • 垃圾收集-这是一个单独的主题,它是一个研究领域,仅出于完整性的目的而提及。重要的是要理解,即使您不打算过于频繁地释放已分配的内存,GC仍可用于帮助分析已分配的内存,为下一次有效的内存分配准备内部数据结构。空闲CPU时间可以说是完成此任务的最佳时机。但是,该主题超出了此问题的范围。