【问题标题】:Optimization of C program with SLAB-like technologies使用类 SLAB 技术优化 C 程序
【发布时间】:2012-02-28 16:19:20
【问题描述】:

我有一个高度密集使用 malloc/free 函数的编程项目。 它具有三种类型的结构,具有非常高的动态和大数字。通过这种方式,malloc和free被大量使用,每秒调用数千次。用用户空间版本的 SLAB 替换标准内存分配可以解决这个问题吗?有没有这种算法的实现?

附:

  1. 系统面向 Linux。
  2. 结构的大小小于 100 字节。
  3. 最后,我更喜欢使用现成的实现,因为内存管理确实是个难题。

【问题讨论】:

  • @BlagovestBuyukliev:谢谢,如果我实现自己的 SLAB,那将非常有用。有些想法很有趣,而且我的内存管理能力不是很强,所以会有所帮助。
  • +1 用于识别内存管理很难并要求现有的实现。

标签: c optimization memory-management


【解决方案1】:

如果您只有三个不同的,那么您将通过使用池分配器(定制或类似 boost::pool 但用于 C)获得很大收益。 Doug Lea's binning based malloc 可以作为池分配器的一个很好的基础(它在 glibc 中使用)。

但是,您还需要考虑其他因素,例如多线程和内存重用(对象会被分配、释放然后重新分配还是只是分配然后释放?)。从这个角度,您可以查看tcmalloc(专为极端分配,包括数量和内存使用)、nedmalloc 或囤积。所有这些分配器都是开源的,因此可以轻松更改以适应您分配的对象的大小。

【讨论】:

  • 问题被标记为“C”。大概提升不可用。 (哎呀,你说'like boost::pool',对不起。)顺便说一句,很棒的链接。
  • @Kaganar:这就是我说“喜欢”的原因,不幸的是,除了boost::pool,我不知道任何池分配器。但我会修改它。
  • @Necrolis:谢谢,我正在考虑我自己的实现,针对我的目标进行了优化,内存重用和大粒度分配。但这似乎是对自行车的重新发明。
【解决方案2】:

如果不了解更多信息,就不可能给您一个好的答案,但是,管理您自己的内存(通常通过分配一个大块,然后在该大块中进行自己的分配)可以避免与通用目的相关的高成本内存管理器。例如,在 Windows 中,许多小的分配将导致性能下降。几乎每种类型的内存管理器都存在现有的实现,但我不确定您到底要的是哪种...

在 Windows 中编程时,我发现调用 malloc/free 就像是性能的死亡 - 几乎所有通过批处理来摊销内存分配的应用内内存分配都会在分配/释放时为您节省大量的处理器时间,所以它可能不会只要您不调用默认分配器,您使用哪种方法非常重要。

话虽如此,这里有一些简单的多线程想法:

This严格来说不是slab管理器,但似乎达到了很好的平衡,也很常用。

我个人发现我经常最终使用一个实现相当简单的内存重用管理器来处理相同大小的内存块——它维护一个固定大小的未使用内存的链表并分配一个新的内存块需要的时候。这里的技巧是将链表的指针存储在未使用的内存块中——这样就会有非常小的四个字节的开销。每当重用内存时,整个过程都是 O(1)。当它必须分配内存时,它会调用一个slab分配器(它本身很简单。)

对于纯仅分配的slab分配器,您只需要求系统(很好地)给您一大块内存并跟踪您尚未使用的空间(只需维护一个指向未使用的开头的指针区域和指向末尾的指针)。当你没有足够的空间来分配请求的大小时,分配一个新的slab。 (对于大块,只需传递给系统分配器。)

链接这些方法的问题?您的应用程序永远不会释放任何内存,但对性能至关重要的应用程序通常要么是一次性处理应用程序,要么是创建许多相同大小的对象然后停止使用它们。

如果你小心点,即使只是原子操作,上述方法也不难让多线程友好。

【讨论】:

    【解决方案3】:

    我最近实现了自己的用户空间slab分配器,对于大量固定大小的分配,它被证明比malloc/free更有效(速度和内存方面)。你可以找到它here

    分配和释放工作在 O(1) 时间内完成,并且由于使用位向量表示空/满插槽而加快了速度。分配时,__builtin_ctzll GCC 内在函数用于定位位向量中的第一个设置位(表示一个空槽),这应该转换为现代硬件上的单个指令。释放时,指针本身会进行一些巧妙的按位运算,以定位对应的slab的header并将对应的slot标记为空闲。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-08
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多