【图像算法优化】开篇:simd-library介绍及几个优化技巧

本系列主要涉及图像处理算法的优化技巧,都是通过学习simd-library中的代码,然后进行总结,包括basic部分跟neon优化部分。

simd-library是用于图像处理的算法库,里面大量的用了SIMD指令对常用的图像处理算法进行优化,github的项目地址为:https://github.com/ermig1979/Simd

本文先开个胃,介绍下几个觉得挺有意思的函数:

摘取自:https://github.com/ermig1979/Simd/blob/master/src/Simd/SimdMath.h

1、求平均

SIMD_INLINE int Average(int a, int b)
{
    return (a + b + 1) >> 1;
}

SIMD_INLINE int Average(int a, int b, int c, int d)
{
    return (a + b + c + d + 2) >> 2;
}

可以看到这里有两个点需要注意:
1) inline的用法:对于这种比较轻量又经常用到的操作,可以写成inline函数,省去频繁调用的堆栈问题,提升效率。当然,在c语言中,也可以用宏定义代替。

2)可以看到这里都有 +1跟+2的操作,使得最终结果有四舍五入的效果

2、排序

SIMD_INLINE void SortU8(int & a, int & b)
{
    int d = a - b;
    int m = ~(d >> 8);
    b += d & m;
    a -= d & m;
}

这里将把输入a,b按照大小进行排序,如果a < b,则不变;否则,交换数值。

逐步过程如下:
if d > 0 , then:
d>>8, d= 0; m = 0xffffffff;
b+= (a-b) = a; a -=(a-b) = b;
if d < 0 , then:
d>>8, d =0xffffffff; m = 0;
b+=0=b; a-=0=a;

这里的trick相当于就是:通过移位来获取数值的符号信息。
从函数名可以知道,这是用于8bit的数值,所以右移8bit可以获取到该数值的符号。在计算机中,负数右移后会得到0xffff ffff;而正数则是0x0。然后通过位操作来得到最终的结果,避免采用条件判断的方式来提升性能。

类似的,还有以下几个函数,也是用的类似的技巧:

3、绝对值差,最大值,最小值

SIMD_INLINE int AbsDifferenceU8(int a, int b)
{
    int d = a - b;
    int m = d >> 8;
    return (d & ~m)|(-d & m);
}
SIMD_INLINE int MaxU8(int a, int b)
{
    int d = a - b;
    int m = ~(d >> 8);
    return b + (d & m);
}
SIMD_INLINE int MinU8(int a, int b)
{
    int d = a - b;
    int m = ~(d >> 8);
    return a - (d & m);
}

SIMD_INLINE int SaturatedSubtractionU8(int a, int b)
{
    int d = a - b;
    int m = ~(d >> 8);
    return (d & m);
}

后续将根据不同的算法,详述算法过程及对应的优化技巧。

你可能感兴趣的:(【图像算法】,图像处理优化技巧)