You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:53:22