views:

76

answers:

4

Hi All I have just learnt that in C language malloc function comes with the issue of thread contention when used in a multi-threaded applications.

In C++ does operator new suffer from the same problem? If yes what tecnhique can I use to avoid this that sounds like a big penalty in the application performance?

Thaks AFG

+1  A: 

That "issue" of thread contention really depends on the implementation. Some of the implementations of malloc in common use were not originally designed with multithreading in mind. But a malloc implementation designed for multithreaded applications shouldn't suffer from contention in normal circumstances.

As an example of a malloc implementation designed with multithreading in mind, look at jemalloc.

ninjalj
A: 

Depending on the implementations of new but as it is usually malloc based yes. Here few thing you can do :

  • Use a profiler to count the number of calls to malloc() (and maybe brk()) per seconds, make sure you have a contention problem with malloc().
  • Try to work with a parallel memory allocator (ie. hoard)
  • Use the stack whenever it's possible : do not call new when you don't need to. Also remember that small copies are usually more cache friendly than pointers and data shared among threads.
Ben
A: 

In C++ does operator new suffer from the same problem?

Yes, in most implementations, it does.

If you are in C++ already, Threading Building Blocks is a C++ template library that should suit your needs. It has scalable allocators, data structures, a website and more...

andras
A: 

The problem with thread contention in malloc comes down simply that the heap must be protected by a mutex of similar device whenever it is updated. If two threads update the heap simultaneously you will have a race condition. The same problem applies to new so there is no fundamental reason why one should have less contention than the next.

Having said that, there are a number of tricks to minimize contention. The first is to break the heap up into separate Arenas. Each Arena has its own lock. If a thread tries to allocate memory and the one Arena is locked, it just tries to allocate off the next Arena.

Frees will need to access the same Arena that was used for a malloc. This can also be optimized by place the pointer to be freed onto a free list. This can be done atomically. When next the Arena becomes unlocked, all the pointers on the free list will get freed properly.

These techniques help prevent but do not eliminate contention which means in a producer consumer threading model, you may be better off having the consumer pass pointers back to the producer where they can be reused or deleted as appropriate.

doron