什么是非时间流加载固有 (_mm256_stream_load_si256) 的浮点 (__m256d) 版本?

What is the floating-point (__m256d) version of the non-temporal streaming load intrinsic (_mm256_stream_load_si256)?

在 AVX/AVX2 中我只能找到 _mm256_stream_load_si256() ,这是 __m256i 的。没有办法流式加载 __m256d 吗?为什么? (我想在不污染 CPU 缓存的情况下加载它)

下面的操作(激进的铸造)有没有障碍?

__m256d *pDest = /* ... */;
__m256d *pSrc = /* ... */;

/* ... */

const __m256i iWeight = _mm256_stream_load_si256(reinterpret_cast<const __m256i*>(pSrc));
const __m256d prior = _mm256_div_pd(*reinterpret_cast<const __m256d*>(&iWeight), divisor);
_mm256_stream_pd(reinterpret_cast<double*>(pDest), prior);

_mm256_stream_load_si256() 内在对应于 (V)MOVNTDQA instruction。这是 非时间加载指令,因此这是您 必须 使用的指令,即使您正在加载浮点数据。

(其他三个非时间指令只做 stores(V)MOVNTDQ (_mm256_stream_si256) is for double quadword integers, (V)MOVNTPS (_mm256_stream_ps) is for packed single-precision floating-point values, and (V)MOVNTPD (_mm256_stream_pd)用于压缩双精度浮点值。)

__m256i*__m256d* 的转换是安全的,反之亦然。这些只是位,它们都存储在 YMM 寄存器中。我从未见过编译器在处理这些类型的转换时遇到问题。不过,可能应该检查生成的汇编代码以确保它没有做一些奇怪的事情!

唯一重要的是在某些处理器上,当您将浮点 SIMD 指令与整数 SIMD 指令混合使用时,会出现跨域惩罚。但由于唯一的 NT 负载是在整数域中,你在这里真的别无选择。

请注意,所有 非临时指令(加载和存储)需要对齐 地址!