x86中“非暂时”内存访问的含义是什么?

时间:2008-08-31 20:18:34

标签: x86 sse assembly

这是一个有点低级别的问题。在x86程序集中,有两个SSE指令:

  

MOVDQA xmmi, m128

  

MOVNTDQA xmmi, m128

IA-32软件开发人员手册中说MOVNTDQA中的 NT 代表非时间,否则它与MOVDQA相同。

我的问题是,非时间是什么意思?

3 个答案:

答案 0 :(得分:131)

非时间SSE指令(MOVNTI,MOVNTQ等)不遵循正常的缓存一致性规则。因此,非临时存储必须遵循SFENCE指令,以便其他处理器及时看到其结果。

当生成数据而不是(立即)再次使用数据时,内存存储操作首先读取完整的高速缓存行然后修改高速缓存的数据这一事实对性能是不利的。此操作将数据从缓存中推出,这可能需要再次使用,以支持不会很快使用的数据。对于大型数据结构(如矩阵)尤其如此,这些数据结构经过填充后再使用。在填充矩阵的最后一个元素之前,绝对大小驱逐了第一个元素,使得写入的缓存无效。

对于此类和类似情况,处理器为非时间写操作提供支持。此上下文中的非时间意味着数据不会很快重用,因此没有理由对其进行缓存。这些非时间写操作不读取高速缓存行然后修改它;相反,新内容直接写入内存。

来源:http://lwn.net/Articles/255364/

答案 1 :(得分:35)

Espo在目标上非常棒。只是想加我的两分钱:

“非时间”短语意味着缺乏时间局部性。缓存利用两种局部性 - 空间和时间,并且通过使用非时间指令,您向处理器发信号通知您不希望在不久的将来使用该数据项。

我对使用缓存控制指令的手动编码程序集持怀疑态度。根据我的经验,这些事情会导致比任何有效的性能提升更多的邪恶错误。

答案 2 :(得分:3)

根据英特尔®64和IA-32架构软件开发人员手册,第1卷:基本架构, “使用Intel Streaming SIMD扩展编程(Intel SSE)”一章:

时间数据与非时间数据的缓存

  

程序引用的数据可以是临时的(数据将再次使用)或非临时的(数据将被引用一次,并且在不久的将来不会重复使用)。例如,程序代码通常是临时的,而多媒体数据(例如3-D图形应用程序中的显示列表)通常不是临时的。为了有效利用处理器的缓存,通常需要缓存时间数据而不缓存非时间数据。用非临时性数据重载处理器的缓存有时被称为“污染缓存”。 SSE和SSE2可缓存性控制指令使程序可以以最小化缓存污染的方式将非临时数据写入内存。

非临时加载和存储指令的描述。 资料来源:英特尔64和IA-32体系结构软件开发人员手册,第2卷:指令集参考

加载(MOVNTDQA-加载双四字非时间对齐提示)

  

如果内存源是WC(写组合)内存类型[...],则使用非时间提示将双四字从源操作数(第二个操作数)加载到目标操作数(第一个操作数)

     

[...]处理器不会将数据读取到缓存层次结构中,也不会从内存中获取相应的缓存行到缓存层次结构中。

请注意,正如彼得·科德斯(Peter Cordes)所言,它在当前处理器上的普通WB(回写)内存上没有用,因为NT提示被忽略(可能是因为没有NT感知的硬件预取器)以及完整的强序加载语义适用。 prefetchnta可用作WB存储器的减少污染负荷

存储(MOVNTDQ-使用非临时提示存储打包的整数)

  

使用非时间提示将源操作数(第二个操作数)中的压缩整数移动到目标操作数(第一个操作数),以防止在写入内存期间缓存数据。

     

[...]处理器不会将数据写入缓存层次结构,也不会从内存中提取相应的缓存行到缓存层次结构中。

使用Cache Write Policies and Performance中定义的术语,可以将它们视为可写(无写分配,无写丢失)。

最后,回顾John McAlpin notes about non-temporal stores可能会很有趣。