代码之家  ›  专栏  ›  技术社区  ›  psaw.mora

内存围栏会阻塞多核CPU中的线程吗?

  •  3
  • psaw.mora  · 技术社区  · 6 年前

    我正在阅读英特尔指令集指南64-ia-32 guide 去了解记忆篱笆。我的问题是,以SFENCE为例,为了确保所有的存储操作都是全局可见的,多核CPU是否会将所有的线程甚至运行在其他核上停驻,直到实现缓存一致性?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Peter Cordes    6 年前

    障碍不会造成 其他 线程/核心等待。他们在当前线程中执行一些操作

    屏障甚至不会让其他线程更快地看到您的加载/存储;CPU核心已经尽可能快地将存储缓冲区中的存储提交(失效)到L1d缓存。(在遵循了所有必要的MESI一致性规则之后,x86的强内存模型只允许存储按程序顺序提交,即使没有障碍)。

    障碍不一定有序 ,他们命令 全球知名度


    mfence (或 lock ed operation 喜欢 lock add xchg [mem], reg 线程等待所有以前的加载和存储完成并全局可见(即刷新存储缓冲区)。

    使用全栅障 Are loads and stores the only instructions that gets reordered? 详细情况。但是 ed操作和 xchg 不是那样的;它们是完全的记忆障碍,但它们仍然允许无序执行 imul eax, edx

    对于超线程,我认为这种暂停发生在每个逻辑线程上,而不是整个内核上。

    但请注意 使用全栅障 手动输入并不能说明如何暂停核心,所以未来的x86实现可以自由地提高它的效率(比如 lock or dword [rsp], 0


    sfence 只有在航班上有新台币商店的情况下才能做任何事情。它根本不命令加载,因此不必停止以后的指令执行。见 Why is (or isn't?) SFENCE + LFENCE equivalent to MFENCE? .

    斯芬斯 屏障可以离开存储缓冲区。(即写合并缓冲区必须刷新)。但在到达存储缓冲区的末尾之前,它可能已经从核心的无序执行部分(ROB或ReOrder缓冲区)中退出

    Does a memory barrier ensure that the cache coherence has been completed?


    lfence 因为记忆障碍几乎是无用的:它只能阻止 movntdqa 从WC内存中加载,通过以后的加载/存储进行重新排序。你几乎不需要那个。

    的实际用例 lfence公司 lfence; rdtsc 在英特尔CPU上,您可以避免 rdtsc 把时钟读得太早,作为一种更便宜的替代方法 cpuid; rdtsc )

    最近的另一个重要用例 lfence公司 是阻止推测性执行(例如,在条件或间接分支之前),以减轻幽灵的影响。这完全基于其部分序列化的英特尔保证的副作用,与其LoadLoad+LoadStore屏障效应无关。

    lfence公司 必须等待存储缓冲区耗尽,然后才能从ROB中退出,因此LFENCE+SFENCE的组合没有MFENCE强。 Why is (or isn't?) SFENCE + LFENCE equivalent to MFENCE?


    相关: When should I use _mm_sfence _mm_lfence and _mm_mfence (用C++代替ASM编写时)。

    请注意,C++的本质类似 _mm_sfence 也阻止编译时内存排序。这通常是必要的,即使当ASM指令本身不是,因为C++编译时重新排序是基于C++的非常弱的内存模型,而不是强的x86内存模型,它适用于编译器生成的ASM。

    所以 _嗯哼 可能会让你的代码工作,但除非你使用NT存储,否则这是过分的。一个更有效的选择是 std::atomic_thread_fence(std::memory_order_release) http://preshing.com/20120625/memory-ordering-at-compile-time/ .