从128位SSE向量加载和提取32位整数值的最有效方法是什么?

时间:2010-12-05 20:18:35

标签: c gcc sse simd

我正在尝试使用SSE内在函数来优化我的代码,但我遇到了一个问题,我不知道在我完成SSE内在函数操作之后从向量中提取整数值的好方法我想要。

有谁知道这样做的好方法?我用C编程,我的编译器是gcc版本4.3.2。

感谢您的帮助。

2 个答案:

答案 0 :(得分:7)

这取决于您对所拥有的最低SSE支持水平的假设。

一直回到SSE2,你有_mm_extract_epi16PEXTRW),它可用于从128位向量中提取任何16位元素。你需要调用它两次以获得32位元素的两半。

在更新版本的SSE(SSE4.1及更高版本)中,您有_mm_extract_epi32PEXTRD),它可以在一条指令中提取32位元素。

或者,如果这不在性能关键循环中,则可以使用联合,例如

typedef union
{
    __m128i v;
    int32_t a[4];
} U32;

答案 1 :(得分:6)

_mm_extract_epi32

提取内在函数确实是最好的选择,但如果你需要支持SSE2,我建议这样做:

inline int get_x(const __m128i& vec){return _mm_cvtsi128_si32 (vec);}
inline int get_y(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0x55));}
inline int get_z(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xAA));}
inline int get_w(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xFF));}

我发现,如果你将向量重新解释为使用任何int [4]表示,那么编译器往往会将内容刷回内存(这可能不是那么糟糕)并将其作为int读回来,尽管我没有看看程序集,看看最新版本的编译器是否能生成更好的代码。