使用SSE获取__m128i向量中的最大值?

Sha*_*ane 12 c x86 assembly sse

我刚刚开始使用SSE,我很困惑如何获得a的最大整数值(max)__m128i.例如:

__m128i t = _mm_setr_ps(0,1,2,3);
// max(t) = 3;
Run Code Online (Sandbox Code Playgroud)

搜索引导我去MAXPS指导,但我似乎无法找到如何使用它"xmmintrin.h".

此外,是否有任何"xmmintrin.h"您建议的文档,而不是查看头文件本身?

Z b*_*son 16

如果有人关心并且因为内在似乎是现在的方式,这里是一个内在的解决方案.

int horizontal_max_Vec4i(__m128i x) {
    __m128i max1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(0,0,3,2));
    __m128i max2 = _mm_max_epi32(x,max1);
    __m128i max3 = _mm_shuffle_epi32(max2, _MM_SHUFFLE(0,0,0,1));
    __m128i max4 = _mm_max_epi32(max2,max3);
    return _mm_cvtsi128_si32(max4);
}
Run Code Online (Sandbox Code Playgroud)

我不知道这是否比这更好:

int horizontal_max_Vec4i(__m128i x) {
    int result[4] __attribute__((aligned(16))) = {0};
    _mm_store_si128((__m128i *) result, x);
    return max(max(max(result[0], result[1]), result[2]), result[3]); 
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*l R 10

如果你发现自己需要对向量进行水平操作,特别是如果它在内部循环中,那么通常表明你正在以错误的方式接近你的SIMD实现.SIMD喜欢在矢量上按元素操作 - 如果你愿意,可以"垂直"操作,而不是水平操作.

至于文档,在intel.com上有一个非常有用的参考,它包含从MMX到各种版本的SSE一直到AVX和AVX-512的所有操作码和内在函数.


Jen*_*ger 8

根据此页面,没有水平最大值,您需要垂直测试元素:

movhlps xmm1,xmm0         ; Move top two floats to lower part of xmm1
maxps   xmm0,xmm1         ; Get maximum of the two sets of floats
pshufd  xmm1,xmm0,$55     ; Move second float to lower part of xmm1
maxps   xmm0,xmm1         ; Get minimum of the two remaining floats
Run Code Online (Sandbox Code Playgroud)

相反,获得最低限度:

movhlps xmm1,xmm0
minps   xmm0,xmm1
pshufd  xmm1,xmm0,$55
minps   xmm0,xmm1
Run Code Online (Sandbox Code Playgroud)

  • maxps指令之间的pshufd在许多CPU(包括Intel)上都有额外的延迟。SSE3`movshdup`将在寄存器的每一半中复制上浮点,因此您可以使用它来避免movaps复制。 (2认同)

Lou*_*cci 5

SSE 中没有水平最大操作码(至少直到我停止跟踪新的 SSE 指令为止)。

所以你不得不做一些洗牌。你最终得到的是......

movhlps %xmm0, %xmm1            # Move top two floats to lower part of %xmm1
maxps   %xmm1, %xmm0            # Get minimum of sets of two floats
pshufd  $0x55, %xmm0, %xmm1     # Move second float to lower part of %xmm1
maxps   %xmm1, %xmm0            # Get minimum of all four floats originally in %xmm0
Run Code Online (Sandbox Code Playgroud)

http://locklessinc.com/articles/instruction_wishlist/

MSDN 记录了内部函数和宏函数映射

http://msdn.microsoft.com/en-us/library/t467de55.aspx