2011-07-27 34 views
1

我正在寻找执行shl(mult(var1,var2),1)操作,其中'mult'乘以var1和var2(两个16位有符号整数)和'shl'shift遗留乘法结果。结果必须饱和,即如果发生上溢或下溢,则为int32 max或int32 min,mult(-32768,-32768)= 2147483647。我需要使用MMX/SSE指令集以有效的方式对多个值进行操作。我虽然关于制作mult(sign_extesion(var1),shl(sign_extension(var2))),但我刚刚发现没有MMX mult()饱和版本存在。你知道任何其他方式来得到它吗?使用MMX汇编程序指令的多加左移操作

回答

3

我认为以下几点应该适合你。只有一个可能的溢出情况下(SHRT_MIN * SHRT_MIN),它明确地处理这个问题:

#include <limits.h> 
#include <mmintrin.h> 

int main(void) 
{   
    __m64 v1 = _mm_set_pi16(0, SHRT_MAX, 0, SHRT_MIN); 
    __m64 v2 = _mm_set_pi16(0, SHRT_MIN, 0, SHRT_MIN); 
    __m64 v = _mm_madd_pi16(v1, v2); // 16 x 16 signed multiply 
    v = _mm_slli_pi32(v, 1);   // shift left by 1 bit to get full range 
    __m64 vcmp = _mm_cmpeq_pi32(v, _mm_set1_pi32(INT_MIN)); 
            // test for SHRT_MIN * SHRT_MIN overflow 
    v = _mm_add_pi32(v, vcmp);  // and correct if needed 

    return 0; 
} 
+0

你有多少增益可以doind乘法通过MMX INSEAD单的人可以得到的先进经验? – LooPer

+0

@LooPer:它取决于CPU,但是大多数当前的Intel CPU有两个整数ALU,所以从2路SIMD可能没有太多的收获。如果你可以去128位SSE,那么你应该看到显着的性能提升,前提是你没有限制内存带宽。 –