这是一个有点低级的问题。在 x86 汇编中有两条 SSE 指令:
MOVDQA xmmi, m128
和
MOVNTDQA xmmi, m128
IA-32 Software Developer's Manual 说 MOVNTDQA 中的NT代表Non-Temporal,否则它与 MOVDQA 相同。
我的问题是,非时间是什么意思?
非临时 SSE 指令(MOVNTI、MOVNTQ 等)不遵循正常的缓存一致性规则。因此,非临时存储必须后跟 SFENCE 指令,以便其他处理器及时看到它们的结果。
当数据产生而不(立即)再次消耗时,内存存储操作首先读取完整的缓存行然后修改缓存数据的事实对性能不利。此操作将可能再次需要的数据从缓存中推出,以支持不会很快使用的数据。对于大型数据结构尤其如此,例如矩阵,它们会被填充然后稍后使用。在填充矩阵的最后一个元素之前,绝对大小会驱逐第一个元素,从而使写入缓存无效。
对于这种情况和类似情况,处理器提供对非临时写操作的支持。在这种情况下,非临时性意味着数据不会很快被重用,因此没有理由缓存它。这些非临时写操作不会读取缓存行然后对其进行修改;相反,新内容直接写入内存。
来源: http: //lwn.net/Articles/255364/
Espo 的目标几乎是爆炸式的。只是想加我的两分钱:
“非时间”短语意味着缺乏时间局部性。缓存利用两种局部性——空间性和时间性,通过使用非时间性指令,您向处理器发出信号,表明您不希望在不久的将来使用该数据项。
我对使用缓存控制指令的手工编码程序集有点怀疑。根据我的经验,这些事情会导致比任何有效的性能提升更多的邪恶错误。
根据 Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 1: Basic Architecture, "Programming with Intel Streaming SIMD Extensions (Intel SSE)" 章节:
缓存时间数据与非时间数据
程序引用的数据可以是临时的(数据将被再次使用)或非临时的(数据将被引用一次并且不会在不久的将来重用)。例如,程序代码通常是临时的,而多媒体数据,例如 3-D 图形应用程序中的显示列表,通常是非临时的。为了有效利用处理器的缓存,通常需要缓存临时数据而不是缓存非临时数据。用非临时数据重载处理器的缓存有时被称为“污染缓存”。SSE 和 SSE2 可缓存性控制指令使程序能够以最小化缓存污染的方式将非临时数据写入内存。
非临时加载和存储指令的描述。资料来源:英特尔 64 和 IA-32 架构软件开发人员手册,第 2 卷:指令集参考
LOAD(MOVNTDQA—加载双四字非时间对齐提示)
如果内存源是 WC(写入组合)内存类型,则使用非临时提示将双四字从源操作数(第二个操作数)加载到目标操作数(第一个操作数)[...]
[...] 处理器不会将数据读入缓存层次结构,也不会将相应的缓存行从内存中提取到缓存层次结构中。
请注意,正如 Peter Cordes 评论的那样,它在当前处理器上的普通 WB(回写)内存上没有用,因为 NT 提示被忽略(可能是因为没有 NT-aware HW 预取器)并且应用了完整的强排序加载语义. prefetchnta
可用作 WB 内存的减少污染负载
STORE(MOVNTDQ - 使用非临时提示存储压缩整数)
使用非临时提示将源操作数(第二个操作数)中的压缩整数移动到目标操作数(第一个操作数),以防止在写入内存期间缓存数据。
[...] 处理器不会将数据写入缓存层次结构,也不会将相应的缓存行从内存中提取到缓存层次结构中。
使用Cache Write Policies and Performance中定义的术语,它们可以被认为是 write-around (no-write-allocate, no-fetch-on-write-miss)。
最后,回顾一下 John McAlpin 关于非临时存储的笔记可能会很有趣。