views:

421

answers:

4

What are all the things one needs to be careful about when coding in a multicore environment?

For example, for a singleton class, it is better to create a global object and then return its reference than a static object.

i.e Rather than having

MyClass & GetInstance()
{

static Myclass singleMyclass;
return singleMyclass;
}

It is better to have

Myclass singleMyclass;

 MyClass & GetInstance()
    {

     return singleMyclass;
    }

GetInstance() might be called by many threads simultaneously.

Edit:

My question was about the hidden constructs of c++ one must be aware of while using them in multithreaded program. In above case static is not thread safe as compiler adds some instructions for static objects, which is not thread safe. I am looking for similar constructs one should be aware of.

A: 

Multicore is not so relevant as you may get multiple threads on a unicore system too.

Both versions of GetInstance() look like they would work there, it's the class methods that need to do proper locking etc if they do anything that is not thread safe.

frankodwyer
+3  A: 

You must be careful with initialisation of statics. The order of initialisation can play havoc in complex system where static objects do lots of things in their constructors.

The first approach is better as singletons are created on demand, but you need some locking to make it thread safe.

The second approach is thread safe as initialisation is done before any threads are created (assuming your static objects do not start threads running), but order or initialisation can be a big problem! What if a static object calls GetInstance() from it's constructor before singleMyclass is instantiated? (Hint: it ain't pretty!)

I would recommend using the first approach, but read up on Double-checked locking, but be careful, because it doesn't actually work

Make sure you read that Dr. Dobb's article.

Daniel Paull
His first example *is* a *static local* variable (in a non-member function that's declared at global scope).
ChrisW
@j: ChrisW is correct here - the instantiation of the local static is deferred until the method is called.
Daniel Paull
ChrisW, Daniel: You're absolutely right, my apologies. I must have *badly* misread the OP's code snippet 8( I've deleted my comment and also my answer, which is irrelevant now.
j_random_hacker
A: 

I was eager about this question based on its title, but fail completely to see the relevance of it, now.

Problems programming multicore is basically, how to structure your program so that those cores get maximum load; in other words, how to parallelize your application.

A warm suggestion in this front, for people with C++ projects, is the Intel Threading Building Blocks library (and book). It tries to take the issues away, hiding them behind template classes. I think it does a pretty good job.

akauppi
+1  A: 

My first answer addressed your example of singleton initialisation, but as you emphasised in an edit to your question, you are after more general pit falls of C++ as we move to multi-core and multi-threaded applications. The following is a real surprise when you first encounter it. Though not C++ specific, it definitely affects C++ code.

Out of order execution and Memory Barriers (or fences):

One gotcha is out of order execution. It is possible for threads to see operations of other threads executing on different cores out of order due to modern hardware allowing out of order execution optimisation. As a result, multi-threaded coded that runs correctly on a single-core machine may in fact be incorrect on a multi-core machine.

A naive solution to such problems is to increase the scope of critical sections. Another is to use memory barriers or lock-free algorithms.

Daniel Paull