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

x86架构下mfence保证顺序一致性的技术疑问

x86架构下mfence指令如何保证顺序一致性的疑问

我正在尝试理解x86架构中mfence指令是如何保证顺序一致性的,以下是示例代码:

std::atomic<int> a,b,r;

void write_a()
{
    a.store(1, std::memory_order_seq_cst);    
}

void write_b()
{
    b.store(1, std::memory_order_seq_cst);    
}

void read_a_b()
{
    while(!a.load(std::memory_order_seq_cst));
    if(b.load(std::memory_order_seq_cst)) {
        r++;
    }
}

void read_b_a()
{
    while(!b.load(std::memory_order_seq_cst));
    if(a.load(std::memory_order_seq_cst)) {
        r++;
    }
}

使用gcc 9.5 -O3编译时,write_a和write_b函数生成的汇编如下:

write_a():
        mov     DWORD PTR a[rip], 1
        mfence
        ret
write_b():
        mov     DWORD PTR b[rip], 1
        mfence
        ret

当使用std::memory_order_release存储时,汇编会去掉mfence:

write_a():
        mov     DWORD PTR a[rip], 1
        ret
write_b():
        mov     DWORD PTR b[rip], 1
        ret

我理解顺序一致性下r==0的结果不可能出现,但获取-释放序下理论上可能出现。

据我所知,mfence会刷新存储缓冲区,后续内存操作需等待mfence前的操作全局完成。但示例中mfence后无其他内存操作,我无法理解它如何影响a、b修改的顺序一致性可见性。

尤其当线程1执行完mov DWORD PTR a[rip], 1但未执行mfence,线程2执行完mov DWORD PTR b[rip], 1但未执行mfence时:

write_a():
        mov     DWORD PTR a[rip], 1 <- thread1 finished this operation
        mfence                      <- thread1 has not yet executed this operation
        ret
write_b():
        mov     DWORD PTR b[rip], 1 <- thread2 finished this operation
        mfence                      <- thread2 has not yet executed this operation
        ret

此时执行的代码与release存储生成的代码一致,仅完成了"release"存储。若线程3执行read_a_b()、线程4执行read_b_a(),我认为它们仍可能对a、b的写入顺序产生分歧,导致r==0的结果理论上仍可能出现,只有当线程1和2执行完mfence后才不会出现这种情况。

我的理解哪里出错了?

注:我知道gcc10使用xchng替代mov+mfence,但核心疑问不变。


内容的提问来源于stack exchange,提问作者dawuald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:12:38