从 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
向量中。其他编译器实际上浪费了上层元素的指令。
我一直在寻找一种将双精度转换为 _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
向量中。其他编译器实际上浪费了上层元素的指令。