从 double 转换为 __m128

Cast from double to __m128

我一直在寻找一种将双精度转换为 _m128 以利用内部指令的方法。

我尝试使用:

double d = 7654321.1234567;
_m128 ret =  *reinterpret_cast<__m128*>(d);

但我当然收到了消息:

error: invalid cast from type ‘double’ to type ‘__m128* {aka __vector(4) float*}’

任何帮助将不胜感激,内联汇编解决方案很好~

假设您实际上想要 double (__m128d) 的向量,您正在寻找 _mm_set_sd(d) 将双精度数零扩展为 __m128d 喜欢 _mm_set_pd(0, d).

参见 Intel's intrinsics guide。我通过在 (double 上搜索以查找采用 double(或 double*)arg.

的内在函数找到了这个。

__m128是4float的向量;你想将 double -> float 转换成向量的低元素吗?喜欢_mm_set_ps(0.f, 0.f, 0.f, d);


您不想将 __m128d* 指向双精度标量,因为向量的宽度是 double 的两倍。如果有什么有意义的话,那就是 (__m128d)d 或它的静态或 reinterpret_cast 版本。

但不幸的是,即使标量 float / double 和 __m128d 自然存在于 XMM 寄存器中,也无法将 double 转换为具有未定义上层元素 AFAIK 的 __m128d。参见 How to merge a scalar into a vector without the compiler wasting an instruction zeroing upper elements? Design limitation in Intel's intrinsics?

如果您只使用标量内在函数然后提取标量结果,一些编译器(很可能仍然只是 clang)可以优化零扩展或广播到 __m128d 向量中。其他编译器实际上浪费了上层元素的指令。