将__m256d转换为__m256i

时间:2018-06-24 16:17:27

标签: c type-conversion intrinsics

由于这样铸造:

 __m256d a;

uint64_t t[4];

_mm256_store_si256( (__m256i*)t, (__m256i)a );/* Cast of 'a' to __m256i not allowed */
在Visual Studio中编译时不允许使用

,我认为我可以使用一些内在函数将__m256d值转换为__m256i,然后再将其传递给 _mm256_store_si256 ,从而避免了引起错误的强制转换

但是在查看that list之后,我找不到一个将__m256d值作为参数并返回__256i值的函数。因此,也许您可​​以帮助我编写自己的函数或查找所需的函数,该函数将4x 64位双精度位值存储到4x64位整数数组中。

编辑:

经过进一步研究,我发现了 _mm256_cvtpd_epi64 正是我想要的。但是,我的CPU不支持AVX512指令集...

我在这里还能做什么?

1 个答案:

答案 0 :(得分:1)

您可以使用 _mm256_store_pd( (double*)t, a) 。我很确定这是严格混叠的安全性,因为您在投射指针后不会直接取消引用指针。 _mm256_store_pd内在函数用任何必要的may-alias东西包装商店。

(使用AVX512,英特尔切换为使用void*来加载/存储内部函数,而不是使用float*double*__m512i*来消除这些笨拙的需求强制转换,并使内部函数可以别名。)

另一种选择是_mm256_castpd_si256__m256d的位重新解释为__m256i

alignas(32) uint64_t t[4];
_mm256_store_si256( (__m256i*)t,  _mm256_castpd_si256(a));

如果您立即从t[]进行读取,则编译器可能会优化存储/重装,而只是重新整理或pextrq rax, xmm0, 1即可将FP位模式直接提取到整数寄存器中。您可以使用内部函数手动编写此代码。但是,存储/重装还不错,特别是如果您希望将double位模式中的1个以上用作标量整数。

您可以可以使用union m256_elements { uint64_t u64[4]; __m256d vecd; };,但是不能保证可以有效地进行编译。


此强制转换将asm指令编译为零,即,它只是一种使C编译器满意的双关语

如果您想将double实际四舍五入为最接近的有符号或无符号64位整数,并且结果为2的补码或无符号二进制而不是IEEE754二进制64,则需要AVX512F _mm256/512_cvtpd_epi64({ {3}})。 SSE2 + x86-64可以实现标量处理,也可以将一些打包的FP hack用于[0..2^52]范围内的数字:vcvtpd2qq


顺便说一句,storeu不需要对齐的目的地,但是store则需要。如果目标是本地目标,则通常应将其对齐,而不是使用未对齐的存储,至少是在存储发生在循环中或者此函数可以内联到更大的函数中时。