_mm_cvtsd_f64高阶浮点的类似物

_mm_cvtsd_f64 analogon for higher order floating point

本文关键字:类似物 f64 mm cvtsd 高阶浮      更新时间:2023-10-16

我正在玩 SIMD,想知道为什么没有类似物来_mm_cvtsd_f64从__m128d中推断出高阶浮点数。

GCC 4.6+有一个扩展,它以一种很好的方式实现了这个目标:

__m128d a = ...;
double d1 = a[0];
double d2 = a[1];

但是在较旧的 GCC(即 4.4)上,我能设法做到这一点的唯一方法是使用 __builtin_ia32_vec_ext_v2df 定义我自己的模拟函数,即:

extern __inline double __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtsd_f64_h (__m128d __A)
{
  return __builtin_ia32_vec_ext_v2df (__A, 1);
}
__m128d a = ...;
double d1 = _mm_cvtsd_f64(a);
double d2 = _mm_cvtsd_f64_h(a);

这真的是要走的路吗?有没有不使用特定于编译器的__builtin东西的替代方案?再说一遍 - 为什么没有_mm_cvtsd_f64_h或类似的预定义?

顺便说一句,我可以想到的这个替代方案要慢得多:

_mm_cvtsd_f64_h(__m128d __A) {
    double d[2];
    _mm_store_pd(d, __A);
    return d[1];
}

我建议你使用以下代码:

inline static _mm_cvtsd_f64_h(__m128d x) {
    return _mm_cvtsd_f64(_mm_unpackhi_pd(x, x));
}

这可能是获取寄存器上半部分xmm最快的方法,它与MSVC/icc/gcc/clang兼容。

你可以只使用联合:

union {
    __m128d v;
    double a[2];
} U;

将您的__m128d分配给 U.v 并回读 U.a[0] 或 U.a[1]。任何像样的编译器都会优化冗余存储和负载。