Очевидно, что вы не можете разветвляться с SIMD, поэтому вам нужно посмотреть, как реализовать эту логику безрассудным способом, используя маски. Я просто дать псевдокод, так что вы получите общее представление - это кодирование должно быть достаточно простой:
bc = b + c ; get `(b + c)` in a vector register
mask = a > bc ; use compare instruction to generate mask (-1 = true, 0 = false)
bc = bc & mask ; use bitwise AND to zero out elements of `(b + c)` which we do not want
a = a & ~mask ; use bitwise ANDC to zero out elements of `a` which we do not want
a = a | bc ; combine required elements into `a` using bitwise OR
bc = b - c ; get `(b - c)` in a vector register
mask = a < bc ; use compare instruction to generate mask (-1 = true, 0 = false)
bc = bc & mask ; use bitwise AND to zero out elements of `(b - c)` which we do not want
a = a & ~mask ; use bitwise ANDC to zero out elements of `a` which we do not want
a = a | bc ; combine required elements into `a` using bitwise OR
Обратите внимание, что я немного схитрил здесь и опустил else
из кода скалярного (при условии, что две ветви являются взаимоисключающими) так, что я реализовал на самом деле эквивалентно:
if (a > b + c) {
a = b + c;
}
if (a < b - c) {
a = b - c;
}
Если это плохое предположение, то вам необходимо сделать некоторые дополнительные битовые операции по реализации логического else
.
Пусть a = 2, b = 2, c = -1 ... Вам нужно будет обработать это еще правильно! (OP использует 's8' intrinsics, поэтому я думаю, что подпись важна для них) –
@James: не обязательно - это зависит от используемого варианта - из контекста обработки изображений и сигналов моя догадка заключается в том, что 'c' всегда положительный - если это не так, но достаточно легко добавить еще несколько поразрядных инструкций для реализации 'else', как я уже сказал выше, но вы не хотите этого делать и жертвуйте производительностью, если это не нужно. –
Маска подписана или без знака? int8x8_t mask; или uint8x8_t mask; – BonderWu