你知道使用MMX/SSE汇编指令添加饱和的32位有符号单词的方法吗?我能找到8/16位版本,但没有32位版本。
你知道使用MMX/SSE汇编指令添加饱和的32位有符号单词的方法吗?我能找到8/16位版本,但没有32位版本。
int saturated_add(int a, int b)
{
int sum = a + (unsigned)b; // avoid signed-overflow UB
if (a >= 0 && b >= 0)
return sum > 0 ? sum : INT32_MAX; // catch positive wraparound
else if (a < 0 && b < 0)
return sum > 0 ? INT32_MIN : sum; // catch negative wraparound
else
return sum; // sum of pos + neg always fits
}
对于无符号数,更加简单,参见这个stackoverflow帖子
在SSE2中,上述操作映射为一系列并行比较和AND / ANDN操作。不幸的是,硬件中没有单个操作可用。
pxor
来进行sum^a
和sum^b
,以及pcmpgt(0, v)
或psrad
。 - Peter Cordes饱和无符号减法很容易,因为对于 `a -= b',我们可以执行
asm (
"pmaxud %1, %0\n\t" // a = max (a,b)
"psubd %1, %0" // a -= b
: "+x" (a)
: "xm" (b)
);
使用SSE。
我正在寻找无符号加法,但可能唯一的方法是将其转换为饱和无符号减法,执行它,然后再转换回来。对于有符号变量也是同样的。
编辑:使用无符号加法,您可以通过这种方式获得min(a, ~b) + b
,这当然有效。对于有符号加法和减法,您有两个饱和边界,这使得事情变得复杂。