neon加速——条件判断

1. 前言

neon加速对图像处理来说(具体到算法/代码上,是指多重循环,二维矩阵的运算),往往能起到奇效,其并行计算的特点能大大加快计算的速度,提高性能。对于其使用方法,网上有不少说明,在此不再累赘。

而对于一些算法来说,条件判断是必不可少的,同时也存在这种情况:对于图像的每个像素点的处理会根据不同的条件有不同的算法式子。那么这时候使用neon加速就比较麻烦了。网上对于这种情况的介绍并没有相关的例子,在此,特写这篇文档以做说明。下面例子忽略多重循环的外包,只对某个元素组进行说明,并且这个条件判断的前提是数值比较。

2. 判断指令

neon对于条件判断的处理,具体使用到:比较,异或,与,取反等基础指令。

  • 比较:相等比较(vceq[q]_type),大于或等于比较(vcge[q]_type)等
  • 异或:veor[q]_type
  • 与: vand[q]_type
  • 取反:vmvn[q]_type,结合异或指令可以成为同或

其中比较指令有个特点:结果为true时,所有位置1,结果为false,所有位置0,所以结果只能为整型
vcgt -> ri = ai > bi ? 1...1:0...0为例:

指令:uint32x4_t vcgtq_f32 (float32x4_t __a, float32x4_t __b);

float32_t data[4] = {2.1,1.2,0.1,3.1};
float32x4_t a = vld1q_f32(data);
float32x4_t b = vdupq_n_f32(2.0);
uint32x4_t res = vcgtq_f32(a, b);//res[0]=0xFFFF,res[1]=0x0,res[2]=0x0,res[3]=0xFFFF

在这里插入图片描述
所以可以得知,当使用判断时,可以将比较为的置位,比较为清零,那么对于真值的条件运算就可以通过指令得到对应元素的运算后的值,假值的则会得的结果为0。下面举例说明。

3. 条件判断例子

以下例子为了简化原理,都使用uint类型进行说明,如果是其他变量类型,都有个转换,截取,扩大的操作,使得代码复杂。

3.1 单if语句

  • C语言代码

    uint fun(uint val)
    {
        uint res = 0;
        if(val > 20)
        {
            res += val;
        }
        return res;
    }
    
  • neon

    uint32x4_t fun_neon(uint32x4_t val)
    {
        uint32x4_t res  = vdupq_n_u32(0);
        uint32x4_t cmp  = vcgtq_u32(val, vdupq_n_u32(20));
        res = vandq_u32(vaddq_u32(res, val), cmp);
        return res;
    }
    

3.2 if…else语句

  • C语言代码

    uint fun(uint val)
    {
        uint res = 100;
        if(val > 20)
        {
            res += val;
        }
        else
        {
            res -= val;
        }
        return res;
    }
    
  • neon

    uint32x4_t fun_neon(uint32x4_t val)
    {
        uint32x4_t res  = vdupq_n_u32(100);
        uint32x4_t cmp  = vcgtq_u32(val, vdupq_n_u32(20));
        uint32x4_t cmp2 = vmvnq_u32(cmp);
        uint32x4_t res1 = vandq_u32(vaddq_u32(res, val), cmp);
        uint32x4_t res2 = vandq_u32(vsubq_u32(res, val), cmp);
        res = vaddq_u32(res1, res2);
        return res;
    }
    

3.3 if…else if…else语句

  • C语言代码

    uint fun(uint val)
    {
        uint res = 100;
        if(val > 20)
        {
           res += val;
        }
        else if(val < 10)
        {
           res -= val;
        }
        else
        {
           res *= val;
        }
           return res;
    }
    
  • neon

    uint32x4_t fun_neon(uint32x4_t val)
    {
        uint32x4_t res  = vdupq_n_u32(100);
        uint32x4_t cmp  = vcgtq_u32(val, vdupq_n_u32(20));
        uint32x4_t cmp2 = vcltq_u32(val, vdupq_n_u32(10))
        uint32x4_t cmp3 = vmvnq_u32(veorq_u32(cmp, cmp2));//同或
        uint32x4_t res1 = vandq_u32(vaddq_u32(res, val), cmp);
        uint32x4_t res2 = vandq_u32(vsubq_u32(res, val), cmp2);
        uint32x4_t res3 = vandq_u32(vmulq_u32(res, val), cmp3);
        res = vaddq_u32(res1, res2);
        res = vaddq_u32(res, res3);
        return res;
    }
    

    博文为ganqiuye原创,转载请附上原文出处链接和本声明。

    4. 结语

在判断条件中使用neon语句在实际上不一定就会比用c语言的普通代码快,因为这个转换的过程比较多,但在整体的算法上,使用neon语句化解这些比较语句还是很有必要的。在实际使用上,需要具体问题具体分析。对于一些难以转换的语句,可以将neon元素vst1出成一个数组,然后再对每个数组的元素进行操作。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值