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

发布于 2024-10-06 07:33:24 字数 155 浏览 3 评论 0原文

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

有谁知道有什么好方法来做到这一点?我正在用 C 编程,我的编译器是 gcc 版本 4.3.2。

感谢您的帮助。

I'm trying to optimize my code using SSE intrinsics but am running into a problem where I don't know of a good way to extract the integer values from a vector after I've done the SSE intrinsics operations to get what I want.

Does anyone know of a good way to do this? I'm programming in C and my compiler is gcc version 4.3.2.

Thanks for all your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无所的.畏惧 2024-10-13 07:33:24

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

一直回到 SSE2,您有 _mm_extract_epi16 (PEXTRW),它可用于从 128 位向量中提取任何 16 位元素。您需要调用此函数两次才能获取 32 位元素的两半。

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

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

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

It depends on what you can assume about the minimum level of SSE support that you have.

Going all the way back to SSE2 you have _mm_extract_epi16 (PEXTRW) which can be used to extract any 16 bit element from a 128 bit vector. You would need to call this twice to get the two halves of a 32 bit element.

In more recent versions of SSE (SSE4.1 and later) you have _mm_extract_epi32 (PEXTRD) which can extract a 32 bit element in one instruction.

Alternatively if this is not inside a performance-critical loop you can just use a union, e.g.

typedef union
{
    __m128i v;
    int32_t a[4];
} U32;
多彩岁月 2024-10-13 07:33:24
_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 读回,尽管我还没有查看程序集以查看最新版本的编译器是否生成更好的代码。

_mm_extract_epi32

The extract intrinsics is indeed the best option but if you need to support SSE2, I'd recommend this:

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));}

I've found that if you reinterpret_cast/union the vector to any int[4] representation the compiler tends to flush things back to memory (which may not be that bad) and reads it back as an int, though I haven't looked at the assembly to see if the latest versions of the compilers generate better code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文