动态内存分配的线程争用

时间:2010-10-10 20:58:07

标签: c++ multithreading contention

我刚刚了解到,在C语言中,malloc函数在多线程应用程序中使用时会出现线程争用问题。

在C ++中,operator new会遇到同样的问题吗?如果是的话,我可以使用tecnhique来避免这种情况,这听起来像应用程序性能上的一个重大损失?

4 个答案:

答案 0 :(得分:2)

线程争用的“问题”实际上取决于实现。常用的malloc的一些实现最初并没有考虑到多线程。但是,为多线程应用程序设计的malloc实现不应该在正常情况下遭受争用。

作为设计时考虑了多线程的malloc实现的一个例子,请看jemalloc

答案 1 :(得分:0)

取决于new的实现,但因为它通常是基于malloc的yes。 你可以做几件事:

  • 使用分析器计算每秒malloc()(可能brk())的呼叫次数,确保malloc()存在争用问题。
  • 尝试使用并行内存分配器(即hoard
  • 尽可能使用堆栈:不需要时不要调用new。 还要记住,小型副本通常比线程之间共享的指针和数据更容易缓存。

答案 2 :(得分:0)

  

在C ++中,运算符new会遇到同样的问题吗?

是的,在大多数实现中,确实如此。

如果您已经使用C ++,Threading Building Blocks是一个C ++模板库,可以满足您的需求。它具有可扩展的分配器,数据结构,website等......

答案 3 :(得分:0)

malloc中的线程争用问题简单地说,无论何时更新,堆都必须受到类似设备的互斥锁的保护。如果两个线程同时更新堆,则会出现争用情况。同样的问题也适用于新问题,因此没有一个根本原因可以解释为什么一个人争论的次数少于下一次。

话虽如此,有一些技巧可以最大限度地减少争用。首先是将堆分成单独的竞技场。每个竞技场都有自己的锁。如果线程试图分配内存并且一个竞技场被锁定,它只是试图分配下一个竞技场。

Frees将需要访问用于malloc的相同Arena。这也可以通过将要释放的指针放在空闲列表上来优化。这可以原子方式完成。当下一个竞技场解锁时,免费列表上的所有指针都将被正确释放。

这些技术有助于防止但不消除争用,这意味着在生产者消费者线程模型中,您可能最好让消费者将指针传递回生产者,以便在适当时可以重复使用或删除它们。