Вы можете написать это как a[n] -= p[n] & ~(a[n] < p[n])
. Обратите внимание, что <
здесь не C, а SSE (pcmpltd
), который возвращает -1 в каждом элементе true и 0 в каждом элементе false (чтобы разрешить операцию AND), а &~
is pandn
. Вот попытка кода:
__m128i a, p;
a = _mm_sub_epi32(a, _mm_andnot_si128(_mm_cmplt_epi32(a, p), p));
Обратите внимание, что для этого используются подписанные операции, и поэтому ваши номера должны оставаться ниже 2^31 - 1
, чтобы они работали правильно. Если вам нужно выйти за пределы этого, измените _mm_cmplt_epi32(a, p)
на _mm_cmplt_epi32(_mm_xor_si128(a, signs), _mm_xor_si128(p, signs))
, где signs
- это вектор 32-битных слов, все элементы которых 0x80000000
. Вот версия, которая, кажется, будет обрабатывать более широкие диапазоны более эффективно:
__m128i a, p;
a = _mm_sub_epi32(a, p);
a = _mm_add_epi32(a, _mm_and_si128(_mm_srai_epi32(a, 31), p));