多线程可以加快内存分配吗?

Nav*_*Nav 14 c++ multithreading memory-management boost-thread new-operator

我正在使用8核处理器,并使用Boost线程来运行大型程序.从逻辑上讲,程序可以分成组,每个组由一个线程运行.在每个组中,一些类总共调用"new"运算符10000次.Rational Quantify表明,"新"内存分配占用了程序运行时的最大处理时间,并且正在减慢整个程序的速度.

我可以加快系统速度的一种方法是在每个"组"中使用线程,这样10000个内存分配可以并行发生.

我不清楚如何在这里管理内存分配.OS调度程序是否真的能够并行分配内存?

Sum*_*uma 12

标准CRT

虽然较旧的Visual Studio默认的CRT分配器是阻塞的,但至少对于Visual Studio 2010及更新版本来说这已不再适用,它直接调用相应的OS函数.Windows堆管理器阻塞,直到Widows XP,在XP中可选的低碎片堆没有阻塞,而默认的是,而较新的操作系统(Vista/Win7)默认使用LFH.最近(Windows 7)分配器的性能非常好,与下面列出的可扩展替换相当(如果针对较旧的平台或者当您需要其他功能时,您仍然可能更喜欢它们).存在多个具有不同许可和不同缺点的多个"可扩展分配器".我认为在Linux上,默认运行时库已经使用了可扩展的分配器(PTMalloc的某种变体).

可扩展的替代品

我知道:

您可能希望检查可扩展内存分配器体验,以了解尝试在Windows项目中使用其中一些内容的经验.

实际上,大多数工作都是通过每线程缓存和每个线程预先分配的分配区域来工作,这意味着小分配通常仅发生在线程的上下文中,OS服务很少被调用.


Mik*_*son 7

动态分配内存使用应用程序/模块/进程的堆(但不是线程).堆一次只能处理一个分配请求.如果您尝试在"并行"线程中分配内存,它们将由堆按适当顺序处理.你不会得到这样的行为:一个线程正在等待获取其内存,而另一个线程可以要求一些,而第三个线程正在获得一些.线程必须在队列中排队才能获得他们的内存块.

你需要的是一堆堆.使用目前不忙的堆来分配内存.但是,你必须要注意这个变量的整个生命周期,以免它在另一个堆上被解除分配(这会导致崩溃).

我知道Win32 API具有诸如GetProcessHeap(),CreateHeap(),HeapAlloc()和HeapFree()之类的函数,它们允许您创建新堆并从特定堆HANDLE分配/释放内存.我不知道其他操作系统中的等价物(我已经找过它们,但无济于事).

当然,您应该尽量避免频繁进行动态分配.但是,如果你不能,你可能会考虑(为了便携性)创建自己的"堆"类(不必是一个堆本身,只是一个非常有效的分配器),可以管理大块内存,当然一个智能指针类,它将保存对它所来自的堆的引用.这将使您能够使用多个堆(确保它们是线程安全的).

  • Mikael,你的陈述不正确.现代堆实现使用线程缓存等技术来加速并行分配.这意味着您可以使用多个并发线程比仅使用一个线程进行更多的分配. (4认同)

Mat*_* M. 5

我知道有两个可扩展的malloc替代品:

我对Hoard没有任何经验(在研究中表现不佳),但是Emery Berger潜伏在这个网站上并对结果感到惊讶.他说他会看一看,我猜测可能有一些特定的测试或实施"困住"Hoard,因为一般的反馈通常是好的.

需要注意的是jemalloc,当您快速创建然后丢弃线程时,它会浪费一些空间(因为它为您分配的每个线程创建一个新池).如果你的线程稳定,那么这应该没有任何问题.