I've been reading about the new C++11 memory model and I've come upon the std::kill_dependency
function (§29.3/14-15). I'm struggling to understand why I would ever want to use it.
I found an example in the N2664 proposal but it didn't help much.
It starts by showing code without std::kill_dependency
. Here, the first line carries a dependency into the second, which carries a dependency into the indexing operation, and then carries a dependency into the do_something_with
function.
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[r2]);
There is further example that uses std::kill_dependency
to break the dependency between the second line and the indexing.
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[std::kill_dependency(r2)]);
As far as I can tell, this means that the indexing and the call to do_something_with
are not dependency ordered before the second line. According to N2664:
This allows the compiler to reorder the call to do_something_with
, for example, by performing speculative optimizations that predict the value of a[r2]
.
In order to make the call to do_something_with
the value a[r2]
is needed. If, hypothetically, the compiler "knows" that the array is filled with zeros, it can optimize that call to do_something_with(0);
and reorder this call relative to the other two instructions as it pleases. It could produce any of:
// 1
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(0);
// 2
r1 = x.load(memory_order_consume);
do_something_with(0);
r2 = r1->index;
// 3
do_something_with(0);
r1 = x.load(memory_order_consume);
r2 = r1->index;
Is my understanding correct?
If do_something_with
synchronizes with another thread by some other means, what does this mean with respect to the ordering of the x.load
call and this other thread?
Assuming my understading is correct, there's still one thing that bugs me: when I'm writing code, what reasons would lead me to choose to kill a dependency?
See Question&Answers more detail:
os