【问题标题】:ARM NEON Intrinsics: Limit values of a vector to 0-255ARM NEON Intrinsics:将向量的值限制为 0-255
【发布时间】:2018-07-24 07:25:40
【问题描述】:

假设我有一个int16x8_t 向量。我想将其值的范围限制为 0-255 并将其转换为 uint8x8_t 向量。将向量读入数组并以传统的非固有方式执行它太慢了。有更快的方法吗?

【问题讨论】:

    标签: c arm simd intrinsics neon


    【解决方案1】:

    您只需要内在函数中的单个指令vqmovun.s16vqmovun_s16

    向量饱和(q)移动无符号窄

    int16x8_t input;
    uint8x8_t result;
    .
    .
    .
    .
    .
    .
    
    result = vqmovun_s16(input);
    

    任何负数元素都将替换为 0,而所有大于 255 的数字将设置为 255,然后缩小为无符号 8 位元素,所有这些都在一个周期内,正是您需要的。

    还有vqmovn_s16 保持带符号的值(-128~127)

    PS:你在做 YUV 到 RGB 的转换吗?那是我需要这条指令的一次。

    【讨论】:

    • 谢谢!不,我只是在做普通的图像卷积。
    【解决方案2】:

    没关系,我找到了方法。它仍然很慢,但它有效:

    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
    【解决方案3】:

    你可以使用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);
    

    【讨论】:

      猜你喜欢
      • 2012-04-07
      • 2023-03-19
      • 1970-01-01
      • 2020-06-02
      • 2012-07-11
      • 2021-10-23
      • 2011-05-28
      • 2022-12-27
      • 2013-01-13
      相关资源
      最近更新 更多