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.

see https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html


Comments

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -