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.

cppreference:

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