c++11 - Relaxed Memory Ordering in C++ -
i trying understand relaxed memory ordering
of c++11. understanding :
this ordering guarantees ordering of operations on particular atomic variable doesn't change ordering of operations of different atomic variables can change. ordering here within same thread. example, thread 1 operation on atomic x operation b on atomic y operation c on atomic y operation d on atomic x relaxed ordering guarantees operation happen-before operation d , operation b happen-before operation c. having said that, ordering of operations between x & y can still change. is, suppose original code above. 1 possible execution order be: operation on atomic x operation d on atomic x operation b on atomic y operation c on atomic y
please correct me if understanding wrong.
i wrote sample code below test relaxed memory ordering
, expected assert
fail sometime. never fails. built program on visual studio 2017
, running on windows 10
intel(r) core(tm) i7-6600u cpu@ 2.60ghz 2.80ghz
class relaxedmemoryordering{ #define array_size 4096 public: static int var_array[array_size]; relaxedmemoryordering() { (int index = 0; index < array_size; ++index) { var_array[index] = 0; } sync1 = 0; sync2 = 0; sync3 = 0; sync4 = 0; sync5 = 0; } void thread1() { sync1.store(1, std::memory_order_relaxed); sync2.store(1, std::memory_order_relaxed); sync3.store(1, std::memory_order_relaxed); (int index = 0; index < array_size; ++index) { var_array[index] = index + 1; } sync4.store(1, std::memory_order_relaxed); sync5.store(1, std::memory_order_relaxed); } void thread2() { while (!sync5.load(std::memory_order_relaxed)) { ; } assert(sync4.load(std::memory_order_relaxed) == 1); (int index = 0; index < array_size; ++index) { assert(relaxedmemoryordering::var_array[index] == (index + 1)); } assert(sync3.load(std::memory_order_relaxed) == 1); assert(sync2.load(std::memory_order_relaxed) == 1); assert(sync1.load(std::memory_order_relaxed) == 1); } void test() { std::thread t1(&relaxedmemoryordering::thread1, this); std::thread t2(&relaxedmemoryordering::thread2, this); t1.join(); t2.join(); } private: std::atomic_int sync1{0}; std::atomic_int sync2{0}; std::atomic_int sync3{0}; std::atomic_int sync4{0}; std::atomic_int sync5{0}; }; static void testrelaxedmemoryordering() { while (1) { { relaxedmemoryordering rmo; rmo.test(); } std::this_thread::sleep_for(std::chrono::milliseconds(10)); }//while loop } int main() { testrelaxedmemoryordering(); }
on intel x86 architecture processors, mov
instruction automatically has acquire-release semantics, might not possible observe reordering expect relaxed semantics. however, should not rely on this, because compiler still allowed reorder instructions optimization purposes.
Comments
Post a Comment