You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ARM NEON中实现x86的_mm256_sign_epi8指令?

在ARM NEON中实现x86 _mm256_sign_epi8的等效功能

首先明确_mm256_sign_epi8(a, b)的核心行为:

对每个8位有符号整数元素:

  • 若b[i] < 0,结果为-a[i]
  • 若b[i] == 0,结果为0
  • 若b[i] > 0,结果为a[i]

ARM NEON没有直接对应的指令,但可以通过位操作和向量选择指令高效实现,且无需乘法:

#include <arm_neon.h>

int8x16_t neon_sign_epi8(int8x16_t a, int8x16_t b) {
    // 提取b的符号位掩码:负数对应0xFF,正数/0对应0x00
    int8x16_t sign_mask = vshrq_n_s8(b, 7);
    // 计算a的取反向量
    int8x16_t neg_a = vnegq_s8(a);
    // 根据符号掩码选择原a或取反后的a
    int8x16_t temp = vbslq_s8(sign_mask, neg_a, a);
    
    // 生成非零掩码:b[i]≠0时为0xFF,否则为0x00
    int8x16_t non_zero_mask = vcgtq_s8(vabsq_s8(b), vdupq_n_s8(0));
    // 将b[i]=0对应的位置置0,得到最终结果
    return vbslq_s8(non_zero_mask, temp, vdupq_n_s8(0));
}

关键指令说明

  • vshrq_n_s8:将向量元素右移7位,直接提取最高位(符号位)并扩展为整个字节的掩码
  • vnegq_s8:直接计算向量元素的相反数,比手动~a +1更高效且符合NEON指令集优化
  • vbslq_s8:基于掩码选择两个向量的对应元素,是NEON实现条件选择的核心指令
  • vcgtq_s8 + vabsq_s8:生成非零掩码,筛选出b中不为0的元素位置

如果你的场景中不需要处理b[i]=0的情况(仅用符号位控制取反),可以简化代码:

int8x16_t neon_sign_only_epi8(int8x16_t a, int8x16_t b) {
    int8x16_t sign_mask = vshrq_n_s8(b, 7);
    int8x16_t neg_a = vnegq_s8(a);
    return vbslq_s8(sign_mask, neg_a, a);
}

内容的提问来源于stack exchange,提问作者Eddie-Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:37:11