我注意到我正在处理的应用程序(用C,BTW编写)充满了realloc
个调用,这些调用由多个线程并行执行。我想让它更快的是使用内存池,所以我可以以非常快的方式扩展原始数组。但是,我不想创建自己的内存池,我想简单地使用一个线程安全的库(或允许多个线程同时创建池)并支持重新分配。
我在这里看过以前的问题,关于同样的问题,但他们未能提供最终的解决方案。例如:
Here提出了同样的问题,但只建议使用Apache运行系统(Hoard是不同的东西),但它就像使用火箭筒杀死蚊子一样。我需要一些简单的东西。
Here所提出的解决方案对我来说太简单了,因为我需要有效的realloc(如果可能的话,在内存中连续扩展chunk)。
重要:显然很多人都认为OPer没有进行任何形式的分析,只是来这里提问。我花了一周的时间来分析我的代码,我知道我的代码现在有多痛苦reallocs
。所以,如果你知道如何回答这个问题,那就是我所需要的。
答案 0 :(得分:0)
您正在寻找的内容似乎是一个可调整大小的内存池。内存池不幸地设计用于固定数量的内存;这就是他们如何最大限度地减少对malloc
,realloc
等的调用。
最后,您可能最好看一下类似malloc
实施的内容(一个要考虑的是Google的TCMalloc;它是gperftools project的一部分)而不是内存池,虽然它是C ++。如果您确定要池,Boost's Pool library值得研究。您可能能够围绕TCMalloc创建一个C包装器,但我不太确定boost :: pool。
如果你想坚持使用C,并且知道你提前分配的内容,你可以创建一个可调整大小的自定义类型,这将有助于优化你的malloc
和{{ 1}}来电。您可以使用简单数组来执行此操作,例如:
realloc
typedef struct {
void *bytes; /* Pointer to the allocated _bytes_. */
size_t n; /* The number of _bytes_ used. */
size_t max; /* The number of _bytes_ allocated. */
} array;
始终是2的某个幂的最小值,并且在使用一定量的内存之前它始终是2的幂。然后,它总是2的倍数,以避免占用太多的内存,max
将永远是真的。这是一个非常简单的观点,但通常是一个好主意。无论何时需要调整数组大小,而不是调用n <= max
,都要检查是否需要首先使用自己的函数调用realloc
,或者是否可以增加使用的字节数({ {1}}在这种情况下)。这是一个通用的实现,适用于标准库函数,如realloc
和任何数据类型。您可能需要一个专门的表单,例如n
:
memcpy
此实现与int
实现之间的区别:typedef struct {
int *ptr; /* Pointer to the allocated _items_. */
size_t n; /* Number of _items_ used. */
size_t max; /* Number of _items_ allocated. */
} int_array;
旨在处理未知类型的内存,这意味着未知的大小。这里的负担是让您保持存储在阵列中的每个对象的类型或至少大小一致。否则,您将有未定义的行为。*这使您能够以合理乐观的方式调整分配的内存大小。
我会说一件事:我不确定这是否会真实地改善您的表现,因为它在大多数情况下会重复malloc
实施的工作。 TCMalloc,假设你把它与这个想法结合起来,用最大约6 MB的内存开始你,并从那里增长,可能是2的倍数或者也许是8的幂。我没有深入检查源,所以我不确定。
*根据ISO C,如果你试图在4字节malloc
中存储一个4字节malloc
,你在技术上会有未定义的行为,但这就是为什么你不应该混合类型,即使它们的大小相同。