【发布时间】:2021-03-28 07:20:23
【问题描述】:
考虑到 16 位无符号加法 (_mm_add_epi16()) 可能溢出,有什么方法可以将 C >= (A + B) 与 SSE2/4.1 指令进行比较?
代码sn-p看起来像-
#define _mm_cmpge_epu16(a, b) _mm_cmpeq_epi16(_mm_max_epu16(a, b), a)
__m128i *a = (__m128i *)&ptr1;
__m128i *b = (__m128i *)&ptr2;
__m128i *c = (__m128i *)&ptr3;
_m128i xa = _mm_lddqu_si128(a);
_m128i xb = _mm_lddqu_si128(b);
_m128i xc = _mm_lddqu_si128(c);
_m128i res = _mm_add_epi16(xa, xb);
_m128i xmm3 = _mm_cmpge_epu16(xc, res);
问题在于,当 16 位加法溢出(回绕)时,大于比较会导致误报。我不能出于我的目的使用饱和添加。我已经在SSE2 integer overflow checking 中查看了检测无符号加法溢出的机制。但是如何使用 if 进行大于比较。
【问题讨论】:
-
我认为您应该首先根据您链接的问题检查溢出。如果您确实检测到溢出,您就知道
C > (A + B)是假的。否则,请检查下一步。由于您正在做向量,因此您可能必须执行这两项检查并使用按位运算合并它们。 (已编辑以修复反向条件)。 -
您要查看
C > (A+B)还是C >= (A+B)?在第一种情况下,我看不出添加饱和度会导致误报。 -
已编辑 - 它的 C >= (A + B)
-
我认为
C-A >= B(带有饱和减法)应该可以工作(未经测试)。编辑:不,它没有(需要更多考虑) -
@PeterCordes 是的,如果
B>0或C>=A之一得到保证,C-A >= B技巧将起作用。 (当然,C-B >= A也类似)。如果我计数正确,可以检查C-min(A,B) >= max(A,B),这将是 5 微秒。
标签: assembly x86 simd sse2 sse4