_mm_stream_load_si128(movntdqa)会修改其参数所指向的内存吗?

4

_mm_stream_load_si128 声明为:

__m128i _mm_stream_load_si128 (__m128i * mem_addr)

虽然_mm_load_si128的声明如下:

__m128i _mm_load_si128 (__m128i const* mem_addr)

这个前面修饰了mem_addr指向的内容吗?如果不是,那么为什么要使用非const声明呢?


@J...:实际上,NT 加载 不会覆盖内存区域的内存顺序语义。在普通 WB 内存上使用 movntdqa 只是当前 CPU 上慢速的 movdqa;它们不会对 NT 提示进行任何操作以尝试最小化缓存污染(例如,只像 prefetchnta 一样加载到 L3 的一个“路”中)。另请参见Non-temporal loads and the hardware prefetcher, do they work together? - 这里有硬件预取器不支持 NT 的情况,因此实际上绕过缓存并没有什么意义。它只对已经弱排序的 WC 内存有用。 - Peter Cordes
@J...你所说的听起来像是在特别谈论NT存储(而不是本问题所涉及的SSE4.1 NT负载),特别是提到了sfence。与其他负载一样,movntdqa负载与sfence无序。movntdqa就是一个负载。SSE2 SIMD-integer NT存储器是movntdq,和其他NT 存储器 一样,确实做到了你所说的覆盖WB内存区域的强Mem-Order语义以更像WC。这就是为什么libc memset / memcpy在大数据复制时使用它。(但不适用于NT加载)。 - Peter Cordes
@PeterCordes 没错,我的想法也是这样。很奇怪,我错过了这是关于负载的,哈哈。可能是有点累了。 - J...
1个回答

4

我认为这样声明没有任何原因。请参见更广泛操作数的 _mm256_stream_load_si256_mm512_stream_load_si512,它们使用 const 参数。

在 Visual Studio 2015 附带的 <smmintrin.h> 中也是使用 const

/*
 * Load double quadword using non-temporal aligned hint
 */

extern __m128i _mm_stream_load_si128(const __m128i*);

底层指令是纯负载,没有任何副作用,甚至不会覆盖内存区域的内存顺序语义。(即它只在WC内存上执行任何特殊操作;在当前CPU上,NT提示在WB(正常写回可缓存)上完全被忽略,因此它只是一个慢速的'movdqa',需要额外的uop。) - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接