Apple M1芯片上C++ seq_cst内存序失效问题咨询
关于std::memory_order_seq_cst在Apple M1上的内存序异常问题
使用std::memory_order_seq_cst内存序时,下述代码理论上不应出现v1 == 0且v2 == 2的情况,但在Apple M1芯片上仍打印出"Reorder happened",无法理解原因。
#include <semaphore.h> #include <cstdio> #include <atomic> #include <thread> std::atomic<int> v1, v2; sem_t start_1, start_2, complete; int main() { sem_init(&start_1, 0, 0); sem_init(&start_2, 0, 0); sem_init(&complete, 0, 0); std::thread t1([&] { while (true) { sem_wait(&start_1); v1.store(1, std::memory_order_seq_cst); asm volatile("":: : "memory"); v2.store(2, std::memory_order_seq_cst); sem_post(&complete); } }); std::thread t2([&] { while (true) { sem_wait(&start_2); int val1 = v1.load(std::memory_order_seq_cst); asm volatile("":: : "memory"); int val2 = v2.load(std::memory_order_seq_cst); if (val1 == 0 && val2 == 2) { puts("Reorder happened"); } sem_post(&complete); } }); for (int i = 0; i < 1000000; i++) { v1 = v2 = 0; sem_post(&start_1); sem_post(&start_2); sem_wait(&complete); sem_wait(&complete); } t1.detach(); t2.detach(); return 0; }
更新:
感谢Peter Cordes的解答,之前忽略了一种线程交错的可能性,但仍对下述代码存在疑惑。使用seq_cst内存序时,r1 == 0且r2 == 0的情况理论上不应发生,该代码在x86 Intel机器上运行正常,但在Apple M1芯片上却出现异常。
#include <thread> #include <semaphore.h> #include <cstdio> #include <atomic> std::atomic<int> v1, v2; std::atomic<int> r1, r2; sem_t start_1, start_2, complete; int main() { sem_init(&start_1, 0, 0); sem_init(&start_2, 0, 0); sem_init(&complete, 0, 0); std::thread t1([&] { while (true) { sem_wait(&start_1); v1.store(1, std::memory_order_seq_cst); asm volatile("":: :"memory"); int val = v2.load(std::memory_order_seq_cst); asm volatile("":: :"memory"); r1.store(val, std::memory_order_seq_cst); sem_post(&complete); } }); std::thread t2([&] { while (true) { sem_wait(&start_2); v2.store(1, std::memory_order_seq_cst); asm volatile("":: :"memory"); int val = v1.load(std::memory_order_seq_cst); asm volatile("":: :"memory"); r2.store(val, std::memory_order_seq_cst); sem_post(&complete); } }); for (int i = 0; i < 1000000; i++) { v1 = v2 = 0; sem_post(&start_1); sem_post(&start_2); sem_wait(&complete); sem_wait(&complete); if (r1 == 0 && r2 == 0) { printf("reorder detected @ %d\n", i); } } t1.detach(); t2.detach(); return 0; }
内容的提问来源于stack exchange,提问作者user19936830
相关产品推荐
相关产品推荐

