使用AVX/AVX2指令,我可以使用以下函数收集8个值的集合,这些值可以是1、2或4字节整数,或者是4字节浮点数:
_mm256_i32gather_epi32()
_mm256_i32gather_ps()
但是目前,我有一个情况,需要加载在nvidia GPU上生成并存储为FP16值的数据。如何进行这些值的矢量化加载?
到目前为止,我找到了_mm256_cvtph_ps()内置函数。
然而,该内置函数的输入是__m128i值,而不是__m256i值。
查看Intel Intrinsics Guide,我没有找到将8个值存储到_mm128i寄存器中的收集操作。
如何将FP16值收集到__m256寄存器的8个通道中? 是否可以将它们作为2字节短整数向量加载到__m256i中,然后以某种方式将其减少到__m128i值,以传递到转换内在函数中? 如果是这样,我还没有找到执行此操作的内在函数。
但结果似乎不是8个正确的值。我认为每隔两个就有一个对我来说是虚假的?
_mm256_i32gather_epi32()
_mm256_i32gather_ps()
但是目前,我有一个情况,需要加载在nvidia GPU上生成并存储为FP16值的数据。如何进行这些值的矢量化加载?
到目前为止,我找到了_mm256_cvtph_ps()内置函数。
然而,该内置函数的输入是__m128i值,而不是__m256i值。
查看Intel Intrinsics Guide,我没有找到将8个值存储到_mm128i寄存器中的收集操作。
如何将FP16值收集到__m256寄存器的8个通道中? 是否可以将它们作为2字节短整数向量加载到__m256i中,然后以某种方式将其减少到__m128i值,以传递到转换内在函数中? 如果是这样,我还没有找到执行此操作的内在函数。
更新
我尝试了@peter-cordes建议的强制转换,但结果是虚假的。 另外,我不明白那怎么能行?
我的2字节int值存储在__m256i中:
0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX
所以我如何将其简单地转换为需要紧密打包的__m128i,如下所示:
XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
强制转换会做到吗?
我的当前代码:
__fp16* fielddensity = ...
__m256i indices = ...
__m256i msk = _mm256_set1_epi32(0xffff);
__m256i d = _mm256_and_si256(_mm256_i32gather_epi32(fielddensity,indices,2), msk);
__m256 v = _mm256_cvtph_ps(_mm256_castsi256_si128(d));
但结果似乎不是8个正确的值。我认为每隔两个就有一个对我来说是虚假的?
__m256i
底部的8个16位元素中,并将其用作__m128i
(使用强制类型转换)。注意,收集数组的顶部元素不能越过未映射的页面。是的,x86仅支持将半精度浮点数转换为/从单精度浮点数(直到某个未来的AVX512)。 - Peter Cordes_mm256_castsi256_si128
将__m256i
转换为__m128i
(尽管 C 风格的转换在大多数编译器上都可以工作)。 - chtz