2014-05-30 - multi-threading is not that obvious

writing multi-threaded program is not easy. using atomics correctly is one step harder. when it comes to relaxed atomics it's a sort of a black-belt level. ;) but to the point…

recently i've read an interesting article: Acquire and Release Fences Don't Work the Way You'd Expect. this is positive meaning – they actually do a bit better, to ensure your code can be easily made valid, at a cost of little naming-confusion. the funny thing is that author point out that Herb Sutter made a mistake himself, explaining how this mechanism works, during his atomic<> weapons talk (which is great, btw – watch it, if you haven't done so yet).

this reminded me of my @ conversation with Hans Boehm regarding his presentation on Going Native 2012: threads and shared variables in C++11 (another great position to watch!). around 31:00 a following pseudo-code example appeared:

if(!initd)
{
  lock_guard<mutex> _(m);
  x=42;
  initd=true;
}
read x;

this is a simplified version of DCLP. in this code, there is a race on “initd”, as it is not atomic and is read and set from multiple threads, at the same time. Hans fixed this by making “initd” atomic, around 46:06. this code however has still a race, this time on “x”. if you look closely, multiple threads may enter “if” statement, all but one will block on locking a mutex, one will proceed, set “x” and unlock. then it uses (reads) x. however threads that were sleeping previously, will now awake and re-set “x”, while others are already reading it. Hans confirmed, this example is oversimplified – what is missing is a second check on “initd”, before setting x. although this conversation took place about 20 months after the initial presentation, he told me i was the first one to notice that.

Hans is the chair of the concurrency work group. Herb is the chair of the whole committee. if these guys make mistakes on their presentations, broadcasted world-wide, this means that the subject is highly non-trivial indeed. it is hard, often non-predictive (it's hard to make such an issue repeatable, say in automated tests) and sometimes hardware-dependent (keep in mind x86* has pretty strong memory model, especially when reading from memory). there are also not that many tools that can help you debug such a conditions. concurrency is now The Way to exploit the hardware, but there is still a long road ahead of us, before it can truly reach the masses.

blog/2014/05/30/multi-threading_is_not_that_obvious.txt · Last modified: 2014/05/30 16:35 by basz
Back to top
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0