代码之家  ›  专栏  ›  技术社区  ›  Dor

最小化malloc()调用的数量可以提高性能?

  •  28
  • Dor  · 技术社区  · 15 年前

    两个应用程序都分配 相同的 内存量(假设为100MB)。
    对于哪个应用程序,下一个malloc()调用会更快,#1还是#2?

    8 回复  |  直到 15 年前
        1
  •  11
  •   benno    15 年前

    当然,这完全取决于malloc实现,但在这种情况下,没有免费调用,大多数malloc实现可能会提供相同的算法速度。

    这假设在这两种情况下为堆分配的内存都足够大。在案例#1中,您将分配更多的总内存,因为每次分配都涉及存储元数据的内存开销,因此您可能需要调用sbrk(),或等效函数来增加案例#1中的堆,这将增加额外的开销。

    由于缓存和其他二阶效应,它们可能会有所不同,因为新分配的内存对齐方式不同。

    如果您一直在释放一些内存块,那么#2可能会更快,因为碎片更少,因此要搜索的可用块列表更小。

    如果您已经释放了所有内存块,那么结果应该是完全相同的,因为任何正常的自由实现都会将这些块合并回一个内存领域。

        2
  •  19
  •   Cheeso    15 年前

    你问了两个问题:

    • 换句话说:malloc()是否有内存中已分配位置的索引?

    至于哪个会更快,这是不可能说的。它取决于分配器算法、机器状态、当前进程中的碎片等。

    不过,您的想法是正确的:您应该考虑malloc的使用将如何影响性能。 我曾经写过一个应用程序,它使用了大量的小内存块,每个内存块都分配有malloc()。它工作正常,但速度很慢。我用一个电话代替了对malloc的多次呼叫,然后在我的应用程序中分割了这一大块。速度快得多。

    我不推荐这种方法;这只是一个例子,说明了malloc的使用会对性能产生重大影响。

    我的建议是 测量它 .

        3
  •  6
  •   Jason Williams    15 年前

    • 你打malloc的次数越多,所花的时间就越多——因此减少打电话的次数会给你带来速度的提升(尽管这是否重要取决于你的具体情况)。

    • 此外,如果您malloc了许多小的块,那么当您释放这些块时,您将比只分配和释放几个大的块时对堆进行更多的碎片化。因此,堆上可能会有许多小的空闲块,而不是几个大的块,因此您的malloc可能需要在空闲空间列表中进一步搜索,以找到合适的块进行分配。这也会让他们更慢。

        4
  •  3
  •   asveikau    15 年前

    free() 将内存插入空闲块列表中。 malloc() malloc() 请求内核提供更多内存。

    另一个原因是 malloc() 如果从多个线程调用,则必须在这些全局结构上进行某种同步(i、 存在 使用不同的优化方案实现,以使多线程更好,但通常情况下,保持多线程安全会增加成本,因为多个线程将争夺这些锁并相互阻止进程。

        5
  •  3
  •   Hans Passant    15 年前

    你可以 总是 使用malloc()分配一大块内存并自己进行细分,这样做会更好。Malloc()经过优化,可以在一般情况下正常工作,并且不假设您是否使用线程,也不假设程序的分配大小。

    实现自己的子分配器是否是一个好主意是第二个问题。很少,显式内存管理已经足够困难了。如果没有任何好的调试方法,您很少需要另一层代码来破坏和崩溃您的程序。除非您正在编写调试分配器。

        6
  •  2
  •   Erik Elmgren    15 年前

    答案是这要看情况而定,大部分潜在的慢度来自malloc()和free()的组合,通常#1和#2的速度相似。

    所有malloc()实现都有索引机制,但向索引中添加新块的速度通常不取决于索引中已有的块数。

    malloc的大部分缓慢性来自两个方面

    • 在先前释放的(块)中搜索合适的空闲块

    编写自己的几乎符合标准的malloc()替换工具malloc()&free()从35%增加到3-4%,它对这两个因素进行了认真的优化。使用其他一些高性能malloc的速度可能与之类似,但拥有我们自己的malloc对于深奥的设备来说更具可移植性,当然也允许在某些地方进行免费内联。

        7
  •  1
  •   Richard Pennington    15 年前

    换句话说,如果我调用malloc(14)100次或malloc(1400)一次,开销将大致相同。我只需要自己管理分配的更大内存块。

        8
  •  1
  •   Thomas Matthews    15 年前

    分配一个内存块比分配多个内存块快。有系统调用的开销,也有搜索可用块的开销。在编程中,减少操作数通常会加快执行时间。

    内存分配器可能必须进行搜索才能找到大小正确的内存块。这增加了执行时间的开销。

    如果您的程序正在分配和销毁许多小的内存块,那么您可能需要考虑分配一个静态数组并将其用于内存中。