2

在评估内存分配时应该检查哪些特征?

分配和解除分配的性能?简单的压力测试就足够了吗?如何检查分配的质量?

例如,我找到了 Oracle 对 malloc的测试,但这只是 Oracle 对问题的看法。而且这个测试只针对多线程性能。

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

4

4 回答 4

4

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

第一步 - 使比较方法成为可能

确定你看重的品质。列出清单,确定优先级,最后制定价值函数。

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

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

第二步 - 设备测试场景

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

第三步 - 测试

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

第四步 - 评估和重新迭代

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

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

于 2013-04-19T08:27:19.513 回答
3

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

于 2013-04-19T07:58:14.753 回答
1

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

如果您正在编写自定义内存分配器,您可能知道它的特点。例如。如果您希望分配器允许您快速分配大量小对象并且您并不真正关心内存使用开销,那么当您为大对象创建分配器并且想要节省尽可能多的内存时,您可能应该进行不同的测试即使以 CPU 时间为代价,这也是可能的。

压力测试总是好的,因为它可以帮助您找到一些竞争条件并检查您的分配器是否没有错误,但性能测试取决于您想要达到的目标。

于 2013-04-19T07:52:31.567 回答
1

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

  • 实现开销- 保持分配的内部数据结构可操作需要多少内存。此外,如果这些结构随着时间的推移而增长或预先分配一次(两种方法都有优点和缺点,并且都是有效的)。
  • 操作效率- 分配/释放内存块需要多长时间。在这里,分配通常是一个挑战,因为它几乎从来都不是一个恒定的时间,并且取决于先前分配的内存块的特性。释放块看起来很简单,但如果与内存碎片整理结合使用,则值得进一步关注(此处不再赘述)。
  • 线程安全与分配本身的关系不大,而与在系统中使用某些解决方案的决定有关。基本上在这里,如果你没有线程 - 没有什么可担心的。如果您确实有线程 - 请确保您的分配在工作时不会被中断。
  • 内存碎片- 分配内存的实际布局。这里有两个完全矛盾的要求在起作用——一旦在缓冲区中找到正确的位置就进行分配,或者确保尽可能少地产生碎片。前者速度快,而后者对资源更友好(也可能更慢)。
  • 垃圾收集- 这是一个单独的主题和一个独立的研究领域,只是为了完整起见才提到它。重要的是要理解,即使您不打算经常释放分配的内存,GC 仍然可以用于帮助分析已分配的内存,为下一次有效的内存分配准备内部数据结构。可以说,空闲 CPU 时间是执行此管家任务的最佳时机。但是,此主题超出了此问题的范围。
于 2020-06-23T11:17:41.393 回答