ARM NEON Intrinsics: предельные значения вектора 0-255

c arm simd intrinsics neon

154 просмотра

3 ответа

Скажи, у меня есть int16x8_tвектор. Я хочу ограничить диапазон его значений до 0-255 и преобразовать его в uint8x8_tвектор. Считывание вектора в массив и выполнение его традиционным не внутренним способом является слишком медленным. Есть ли более быстрый способ?

Автор: Kevin Qiu Источник Размещён: 01.08.2019 09:21

Ответы (3)


3 плюса

Решение

Все, что вам нужно, это единственная инструкция vqmovun.s16, vqmovun_s16по сути.

Вектор, насыщающий (q) Перемещение без знака Узкая

int16x8_t input;
uint8x8_t result;
.
.
.
.
.
.

result = vqmovun_s16(input);

Любой отрицательный элемент будет заменен на 0, в то время как все числа больше 255 будут установлены как 255, затем сузятся до 8-битных элементов без знака, и все это в одном цикле, именно то, что вам нужно.

Существует также, vqmovn_s16который сохраняет значения в подписи (-128 ~ 127)

PS: вы работаете над преобразованием YUV в RGB? Это был один раз, когда мне понадобилась эта инструкция.

Автор: Jake 'Alquimista' LEE Размещён: 24.07.2018 09:04

0 плюса

Неважно, я нашел способ. Это все еще довольно медленно, но работает:

int16x8_t q_result;
int16x8_t max_value = vdupq_n_s16(255);
int16x8_t min_value = vdupq_n_s16(0);
uint16x8_t max_mask, min_mask;
max_mask = vcgtq_s16(q_result, max_value);
min_mask = vcltq_s16(q_result, min_value);
q_result = vbslq_s16(max_mask, max_value, q_result);
q_result = vbslq_s16(min_mask, min_value, q_result);
Автор: Kevin Qiu Размещён: 24.07.2018 07:41

0 плюса

Вы можете просто использовать vmaxq_s16/ vminq_s16:

const int16x8_t max_value = vdupq_n_s16(255);
const int16x8_t min_value = vdupq_n_s16(0);
int16x8_t q_result = ...;
q_result = vmaxq_s16(min_value, q_result);
q_result = vminq_s16(max_value, q_result);
Автор: Paul R Размещён: 24.07.2018 09:07
Вопросы из категории :
32x32