ARM NEON Intrinsics:将向量的值限制为 0-255
ARM NEON Intrinsics: Limit values of a vector to 0-255
假设我有一个 int16x8_t
向量。我想将其值的范围限制为 0-255 并将其转换为 uint8x8_t
向量。将向量读入数组并以传统的非固有方式执行它太慢了。有没有更快的方法?
没关系,我找到了办法。它仍然很慢,但它有效:
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);
你可以直接使用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);
您只需要内在函数中的单个指令 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 的转换吗?那是我需要此说明的一次。
假设我有一个 int16x8_t
向量。我想将其值的范围限制为 0-255 并将其转换为 uint8x8_t
向量。将向量读入数组并以传统的非固有方式执行它太慢了。有没有更快的方法?
没关系,我找到了办法。它仍然很慢,但它有效:
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);
你可以直接使用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);
您只需要内在函数中的单个指令 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 的转换吗?那是我需要此说明的一次。