Есть ли способ выполнить сравнение, подобное C ›= (A + B) с инструкциями SSE2/4.1, учитывая, что 16-битное сложение без знака (_mm_add_epi16()
) может переполниться?
Фрагмент кода выглядит так:
#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 . Но как мне использовать if для большего, чем сравнение.
C > (A + B)
ложно. В противном случае проверьте следующее. Поскольку вы работаете с векторами, вам, возможно, придется выполнять обе проверки и объединять их с помощью побитовых операций. (Отредактировано, чтобы исправить обратное условие). - person Jester   schedule 17.12.2020C > (A+B)
илиC >= (A+B)
? В первом случае я не вижу, как добавление с насыщением приводит к ложным срабатываниям. - person chtz   schedule 17.12.2020C-A >= B
(с насыщенным вычитанием) должен работать (не проверено). Редактировать: Нет, это не так (нужно подумать об этом больше) - person chtz   schedule 17.12.2020C
не может быть0xffff
, поможет ли это выполнить насыщениеA+B
, а затем сдвинуть по диапазону как C, так и сумму со знаком (путем перестановки их битов знака сpxor
) дляpcmpgtw
? Но если это должно работать для C = 0xffff, как и результат насыщения, я не думаю, что это помогает. - person Peter Cordes   schedule 18.12.2020C-A >= B
сработает, если гарантировано одно изB>0
илиC>=A
. (Аналогично дляC-B >= A
, конечно). Можно было бы проверитьC-min(A,B) >= max(A,B)
, что будет 5 мкп, если я правильно считаю. - person chtz   schedule 18.12.2020