【问题标题】:Cast from double to __m128从 double 转换为 __m128
【发布时间】:2020-07-22 19:40:13
【问题描述】:

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

我尝试使用:

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

但我当然得到了消息:

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

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

【问题讨论】:

  • __m128 ret = *reinterpret_cast&lt;__m128*&gt;(d); -> __m128 ret = *reinterpret_cast&lt;__m128*&gt;(&amp;d);

标签: c++ assembly sse inline-assembly intrinsics


【解决方案1】:

假设您实际上想要double (__m128d) 的向量,您正在寻找 _mm_set_sd(d) 以将双精度零扩展到 __m128d,例如 _mm_set_pd(0, d)

Intel's intrinsics guide。我通过搜索 (double 找到了这个,以查找采用 double(或 double*)arg 的内在函数。

__m128是4个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 向量中。其他编译器实际上在上层元素上浪费了指令。

【讨论】:

    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2019-05-20
    • 1970-01-01
    • 2015-10-22
    • 2023-04-01
    相关资源
    最近更新 更多