通过索引获取__m128的成员?

时间:2012-09-27 15:06:07

标签: c++ clang sse simd intrinsics

我有一些代码,最初是由MSVC工作人员给我的,而我正试图让它在Clang上工作。这是我遇到问题的功能:

float vectorGetByIndex( __m128 V, unsigned int i )
{
    assert( i <= 3 );
    return V.m128_f32[i];
}

我得到的错误如下:

Member reference has base type '__m128' is not a structure or union.

我环顾四周,发现Clang(也许是GCC)在将__m128视为结构或联合时遇到了问题。但是我还没有找到一个直接的答案,我怎么能得到这些价值。我已经尝试使用下标运算符而无法做到这一点,我已经浏览了大量的SSE内在函数列表并且尚未找到合适的函数。

5 个答案:

答案 0 :(得分:18)

联盟可能是最便携的方式:

union {
    __m128 v;    // SSE 4 x float vector
    float a[4];  // scalar array of 4 floats
} U;

float vectorGetByIndex(__m128 V, unsigned int i)
{
    U u;

    assert(i <= 3);
    u.v = V;
    return u.a[i];
}

答案 1 :(得分:17)

即使SSE4.1可用且i是编译时常量,也不能以这种方式使用pextract等:

// broken code starts here
template<unsigned i>
float vectorGetByIndex( __m128 V) {
    return _mm_extract_epi32(V, i);
}
// broken code ends here

我不删除它,因为它是一个有用的提示,如何不做事情,让它成为公众羞辱。

更好地使用

template<unsigned i>
float vectorGetByIndex( __m128 V) {
    union {
        __m128 v;    
        float a[4];  
    } converter;
    converter.v = V;
    return converter.a[i];
}

无论可用的指令集如何都可以使用。

答案 2 :(得分:15)

作为对hirschhornsalz解决方案的修改,如果i是编译时常量,则可以通过使用shuffle / store完全避免联合路径:

template<unsigned i>
float vectorGetByIndex( __m128 V)
{
#ifdef __SSE4_1__
    return _mm_extract_epi32(V, i);
#else
    float ret;
    // shuffle V so that the element that you want is moved to the least-
    // significant element of the vector (V[0])
    V = _mm_shuffle_ps(V, V, _MM_SHUFFLE(i, i, i, i));
    // return the value in V[0]
    return _mm_cvtss_f32(V);
#endif
}

答案 3 :(得分:4)

我使用的方式是

union vec { __m128 sse, float f[4] };

float accessmember(__m128 v, int index)
{
    vec v.sse = v;
    return v.f[index];
}

似乎很适合我。

答案 4 :(得分:0)

参加晚会但发现这在 MSVC 中对我有用,其中 z 是 __m128 类型的变量。

#define _mm_extract_f32(v, i)       _mm_cvtss_f32(_mm_shuffle_ps(v, v, i))

__m128 z = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);

float f = _mm_extract_f32(z, 2);

或者更简单

__m128 z;

float f = z.m128_f32[2];  // to get the 3rd float value in the vector