【问题标题】:What is a good size for medium sized memory allocations?中型内存分配的合适大小是多少?
【发布时间】:2011-07-31 06:58:15
【问题描述】:

对于序列化系统,我需要分配缓冲区来写入数据。需要的大小事先不知道,所以基本模式是mallocN 字节,如果需要更多则使用reallocN 的大小足以容纳大多数对象,因此很少进行重新分配。

这让我认为malloc 可能比其他人更容易满足的最佳初始字节数。我猜想在pagesize 附近的某个地方,但不一定完全是malloc 需要一些空间来做家务。

现在,我确信这是一个无用的优化,如果它真的很重要,我可以使用一个池,但我很好奇;我不能成为第一个认为给我最容易分配的字节块作为开始的程序员。有没有办法确定这一点?

任何特别适用于现代 GCC/G++ 和/或 linux 的答案都将被接受。

【问题讨论】:

  • 优化本身并不是没用的,但也许您应该等待优化,直到有具体需求?还是您手头有太多时间? :-)
  • @Anders:如果我自己花几个小时研究这个,那可能是在浪费时间。看看是否可以在 SO 上回答我感兴趣的问题对我来说似乎很省时:)
  • @Anders K:根据我的经验,大多数对优化问题有疑问的发帖者都需要输入关于做什么而不是不做什么的意见。

标签: c gcc memory-management premature-optimization page-size


【解决方案1】:

在类似情况下的处理方式是让第一个 malloc 分配一些重要但不太大的块,这将适合大多数情况(如您所述),并且每个后续的 realloc 调用都将请求的大小加倍.

所以,如果一开始你分配 100,下次你将realloc 200,然后是 400、800 等等。这样,每次执行后,后续重新分配的机会就会降低。

如果我没记错的话,std::vector 的行为就是这样。

编辑后

最佳的初始分配大小将是一方面可以涵盖您的大多数情况,但另一方面不会太浪费的那个。如果您的平均病例数为 50,但可能飙升至 500,您将希望最初分配 50,然后每隔一个 realloc 加倍或三倍(或乘以 10),以便您可以在 1-3 @ 中达到 500 987654326@s,但任何进一步的reallocs 都不太可能且不常见。所以这基本上取决于你的使用模式。

【讨论】:

  • 我非常了解这种方法。它根本没有解决问题,这完全与确定初始大小有关。
  • 是的,为此加了两分钱,但你没有提到你为什么要寻找优化,所以我猜这是因为你不想浪费内存。你还有什么想要优化的吗?
  • 问题是关于是否有可能知道 malloc 可以最有效地处理什么中等大小。使用模式,即我实际需要的大小,不是问题的一部分,除了我暗示pagesize 可能没问题。
【解决方案2】:

通过阅读this wiki 页面,您的答案似乎会因您使用的 malloc 的实现和操作系统而有很大差异。阅读 OpenBSD 的 malloc 上的内容特别有趣。听起来您也想查看 mmap,但我猜我会说分配默认页面大小(4096?)会被优化。

【讨论】:

  • 实际上,我很想知道对此进行的实验的结果。也许尝试分配 4095 字节 x 次,看看你的时间平均值是什么样的,然后用 4096 字节和 4097 字节做同样的实验。您需要确保您的页面大小确实设置为 4kb,并且可能希望在每次测试之前重新启动计算机。有接盘侠吗? :-)
【解决方案3】:

我对你的建议是找到一个合适的 malloc/realloc/free 源代码,这样你就可以在同一个源模块(并使用相同的内存结构)中实现你自己的“malloc_first”,它只是分配和返回大于或等于传递的 minimum_bytes 参数的第一个可用块。如果通过 0,您将获得第一个区块周期。

适当的声明可以是

void *malloc_first (size_t minimum_bytes, size_t *actual_bytes);

我不知道这样的任务是否可行。我建议您尝试使用所有源代码都可用的 Linux。

【讨论】:

  • 是的,我猜。但在这一点上,我可能会更好地使用内存池(已经有专家实现)和一个简单的分配策略。但是您“控制自己”的一般建议可能是正确的。
猜你喜欢
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 2012-03-05
  • 2013-05-29
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多