【问题标题】:Allocate large blocks of contiguous memory - do or don't?分配大块连续内存——做还是不做?
【发布时间】:2012-07-03 15:17:55
【问题描述】:

我一直坚信分配大块连续内存不是一个好习惯。很明显,如果内存碎片发挥作用,您可能会遇到麻烦,在大多数情况下不能确定排除(尤其是在设计为服务等的大型项目中)。

最近我遇到ITK 图像处理库并意识到,它们(实际上)总是将图像数据(甚至是 3D - 这可能是巨大的)分配为一个连续的块。有人告诉我这应该不是问题,至少对于 64 位进程而言。但是,我看不出 64 位和 32 位进程之间的系统差异,除了由于更大的虚拟地址空间可能会延迟发生内存问题。

言归正传:我想知道在处理大量数据时有什么好的做法:简单地将其分配为一个大块,还是将其拆分为更小的块进行分配?

由于问题当然是特定于系统的,我想将其限制为本机(非托管,无 CLR)C++,尤其是在 Windows 下。但是,如果可能的话,我也会对任何更通用的 cmets 感兴趣。

【问题讨论】:

  • 即使是唯一的区别,延迟 2^32 倍也是非常重要的。这意味着一个长时间运行的进程之前在 1 分钟后遇到内存碎片问题,现在在 8000 年后遇到问题。不希望得到关于它的所有 Y2K,直到 8000 年正常运行时间才会出现的问题不是问题。或者至少不是我的问题。
  • 地址大小加倍不会使空间增加一倍,而是空间平方。所以问题会在 64 位系统上很多出现。
  • 求助于编写自己的分配器的人这样做有两个原因:1. 他们被误导了,2. 这是经过大量分析后的绝对最后手段,并且彻底了解了分配器的局限性。默认内存管理系统。那么你属于哪一类呢?我的意思是,使用系统内存管理器,除非这被证明是瓶颈。
  • @Nim 根据您的工作,您管理内存的方式可能会产生重大影响。将图像数据分配到一个连续的块中,而不是将其分段,简化了访问并提高了局部性,这两者都可以显着提高性能。
  • @Nim 您不必编写自己的经理。 IIUC,图像数据在逻辑上是一个大(结构化?)块。在单个new 中分配它可能比将它分成块更容易。 (在我编写自己的内存管理器之前,我会在网上四处寻找malloc 的替代实现。)

标签: c++ memory-management


【解决方案1】:

这个问题似乎很荒谬......让我改写一下来说明:

如果你需要一大块内存并且担心碎片,你应该自己碎片吗?

通过自己进行分段而不是让系统内存管理器为您分段,您不会获得任何好处。系统在这方面做得非常好,你不可能做得更好。

话虽如此,如果在所有条件相同的情况下,您可以执行相同的任务,但将其分解为合理的片段,那么可能值得分析一下您是否可以获得任何东西。但总的来说,您不会在合理的意义上获得任何收益——您将无法超越操作系统。

【讨论】:

  • 我拆分大内存块的目的不是加速碎片化(;)),而是一个(也许也是?)简单的想法:在碎片化内存中我仍然可以分配一块小内存块,但我可能无法分配大块。
  • 啊,您担心内存管理器没有足够的 虚拟 地址空间来满足您的请求,而不是物理内存碎片。在这种情况下,虽然我仍然认为这个问题有点奇怪,因为你已经知道解决方案,你只是在问你是否应该这样做。我认为您可以比其他任何人更好地回答这个问题,但我认为每个人都会同意您应该避免解决尚未被证明存在的问题。确保修复确实物有所值。
  • 感谢您的评论。我现在从这里的讨论中真正理解的一件事(诚然我以前没有)是 32 位和 64 位进程在这方面的严重区别。根据我们的经验,如果软件在 32 位下运行,内存的“切片”对我们来说是绝对必要的——但将来我们可能会在我们专门为 64 位系统开发时忽略它(不幸的是,这还不是案例)。
猜你喜欢
  • 2021-07-06
  • 2010-10-12
  • 2010-12-29
  • 2012-08-19
  • 2019-12-10
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多