由于这样铸造:
__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指令集...
我在这里还能做什么?
答案 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
则需要。如果目标是本地目标,则通常应将其对齐,而不是使用未对齐的存储,至少是在存储发生在循环中或者此函数可以内联到更大的函数中时。