X86 sfence+lfence != mfence

Aug 31, 2020

 x86有lfence sfence 和 mfence来实现内存屏障

但是sfence与lfence组合与mfence并不等价

lfence

lfence保证在屏障前的所有load指令完成

lfence和lfence  lfence和mfence是强顺序的

但是lfence和sfence之间却没有保证属于weak-order

此外在intel文档中 lfence保证在屏障前的所有操作(这里包括store和load)都已经被局部执行。

LFENCE does not execute until all prior instructions have completed locally

当然completed locally并不意味着可见性。

AMD的lfence好像没有相对于的说明

sfence

对于sfence,它将writebuffer中的内容刷掉,随后MESI会保证写值的可见性

但同样sfence和读操作 包括lfence在内,也是weak-order的

Test

下面主要代码来自 /memory_barrier_test

void thread1Func()
{
    while (1)
    {
        sem_wait(&beginSema1);

        X = 1;
#if TEST_SL_FENCE
        asm volatile("sfence" ::
                         : "memory");
        asm volatile("lfence" ::
                         : "memory");
#elif (TEST_M_FENCE)
        asm volatile("mfence" ::
                         : "memory"); // Prevent compiler reordering
#else
        asm volatile("" ::
                         : "memory");
#endif
        r1 = Y;

        sem_post(&endSema);
    }
};

使用TEST_SL_FENCE的时候还是会出现reorder的情况

也就是lfence带着r1 = Y或者thread2Func中lfence带着r2 = X跑到sfence上面去了

而使用mfence则可以保证强顺序

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.