x86 非临时指令:线程本地数据是不是需要围栏?

Posted

技术标签:

【中文标题】x86 非临时指令:线程本地数据是不是需要围栏?【英文标题】:x86 Non-Temporal Instructions: Is fencing ever needed for thread-local data?x86 非临时指令:线程本地数据是否需要围栏? 【发布时间】:2016-06-14 07:08:21 【问题描述】:

在 x86/x64 上,非临时存储指令(例如 MOVNTIMOVNTPS)提供的内存排序保证比“常规”存储要弱。我知道在共享将跨线程非临时写入的内存时,围栏(例如SFENCE)是必要的。但是,线程本地内存是否需要围栏指令?如果我通过MOVNTPS 写入某个位置,是否保证写入对同一线程中的后续指令可见,而无需任何栅栏指令?

【问题讨论】:

单个线程总是按照程序顺序观察其自己的动作。乱序 CPU 的基本规则是它们总是表现得好像您的代码按程序顺序运行一样。 (唯一的例外是当架构有其他规则时:例如 IA-64 是显式并行性的实验,其中每个 VLIW 指令块并行执行。因此您可以在同一指令块中与 a=b, b=a 进行交换或一些东西。我猜一些 RISC 架构中的分支延迟槽是另一个例子。) 可能不存在单线程代码需要隔离任何东西的 ISA。核心可以很容易地窥探自己的存储缓冲区。 【参考方案1】:

是的,它们将在没有栅栏的情况下可见。请参阅英特尔® 64 和 IA-32 架构软件开发人员手册第 3A 卷:系统编程指南,第 1 部分中的 8.2.2 P6 和更新的处理器系列中的内存订购部分其中说,除其他外:

对于定义为可回写缓存的内存区域,[...] 读取可能会使用旧写入重新排序到不同的位置,但 不是旧的写入相同的位置。

对内存的写入不会与其他写入重新排序,与 以下例外: -- 使用非临时移动指令执行的流式存储(写入) (MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS 和 MOVNTPD);

【讨论】:

以上是关于x86 非临时指令:线程本地数据是不是需要围栏?的主要内容,如果未能解决你的问题,请参考以下文章

当前的 x86 架构是不是支持非临时负载(来自“正常”内存)?

原子线程围栏:为什么在这个非原子变量上存在数据竞争?这有关系吗?

在没有任何锁的情况下加入另一个线程后是不是需要内存围栏?

X86 和 ARM架构对比

ARM和X86架构

CPU两大架构X86 和 ARM