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

这是一个比较低级的问题,在 x86汇编中有两个 SSE 指令:

MOVDQA xmmi, m128

还有

MOVNTDQA xmmi, m128

IA-32软件开发者手册上说 MOVNTDQA 中的 新界北代表 非时间的,否则就和 MOVDQA 一样。

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

47001 次浏览

非时态 SSE 指令(MOVNTI、 MOVNTQ 等)不遵循正常的缓存一致性规则。因此,为了让其他处理器及时看到它们的结果,非时态存储必须遵循 SFENT 指令。

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

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

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

埃斯波的目标很准,我只是想补充一下:

“非时间”短语的意思是缺乏时间的局部性。高速缓存利用了两种局部性——空间和时间,通过使用非时间指令,您向处理器发出信号,表示您不希望在不久的将来使用数据项。

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

根据英特尔64和 IA-32架构软件开发人员手册,第1卷: 基本架构, “使用英特尔 SSE 编程(英特尔上海证券交易所)”章节:

时态和非时态数据的缓存

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

非时间加载和存储指令的描述。 资料来源: Intel 64和 IA-32架构软件开发者手册,第2卷: 指令集参考

负载(MOVNTDQA ー负载双四字非时间对齐提示)

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

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

注意,正如 Peter Cordes 所说,它对当前处理器上的普通 WB (回写)内存没有用处,因为 NT 提示被忽略了(可能是因为没有可识别 NT 的 HW 预取器) ,并且应用了完整的强序加载语义。prefetchnta可以作为 WB 存储器的污染减轻负载

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

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

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

使用在 缓存写策略和性能中定义的术语,它们可以被认为是写绕(no-write-distribution,no-get-on-write-miss)。

最后,回顾一下 John McAlpin 提到了非时间存储可能会很有趣。