c++11 - Do C++ conditional statements carry a dependency from the condition expression to the statement? -
i'm asking in memory-model sense. http://en.cppreference.com/w/cpp/atomic/memory_order
i'm asking because want know if can use std::memory_order_consume
in below:
mlocalmemptr1 , 2 , matomicmemptr pointers shared buffer.
in producer thread i'm doing:
for (int x = 0; x < 10; ++x) { ++mlocalmemptr1 *mlocalmemptr1 = x; // <========= matomicmemptr.store(mlocalmemptr1, std::memory_order_release); }
and in consumer:
tempmemptr = matomicmemptr.load(std::memory_order_consume); while (tempmemptr != mlocalmemptr2) { ++mlocalmemptr2; int test = *mlocalmemptr2; // <======== b dosomelongrunningthing(test); tempmemptr = matomicmemptr.load(std::memory_order_consume); }
so dependency chain go tempmemptr -> mlocalmemptr2 -> test -> dosomelongrunningthing?
i'm worried b
may executed before a
. know can use std::memory_order_acquire
, can use consume (which more lightweight) if conditional statement causes memory order dependency.
release-consume ordering
if atomic store in thread tagged std::memory_order_release , atomic load in thread b same variable tagged std::memory_order_consume, memory writes (non-atomic , relaxed atomic) dependency-ordered-before atomic store point of view of thread a, become visible side-effects in thread b, is, once atomic load completed, thread b guaranteed see thread wrote memory if carries data dependency atomic load.
1.10.10:
an evaluation dependency-ordered before evaluation b if
— performs release operation on atomic object m, and, in thread, b performs consume operation on m , reads value written side effect in release sequence headed (...)
1.10.9:
an evaluation carries dependency evaluation b if - value of used operand of b, unless:
— b invocation of specialization of std::kill_dependency (29.3), or
— left operand of built-in logical , (&&, see 5.14) or logical or (||, see 5.15) operator, or
— left operand of conditional (?:, see 5.16) operator, or
— left operand of built-in comma (,) operator (5.18); (...)
basing on these facts mlocalmemptr2
should synchronized. there still question of order of evaluation.
if (atomic.load(std::consume) < x)
which 1 evaluated first unspecified. there no guarantee (as couldn't find in standard) compiler first perform consume operation, refresh shared buffer , load atomic
and then x
.
having not found proof operands evaluated in "wished" way, without explicit decomposition of atomic load mlocalmemptr2
won't work , cpu might read stale value of memory pointed mlocalmemptr2
. memory_order_acquire
not change here, mlocalmemptr2
carries data dependency.
Comments
Post a Comment