OpenCV - Universal intrinsics 统一指令集

8 篇文章 1 订阅

0. OpenCV

用的4.5.2版本。

0.0 详细说明

“通用内部函数(Universal intrinsics)”是一个类型和函数集,旨在简化不同平台上代码的矢量化。目前,在不同的体系结构上支持一些不同的SIMD扩展。各种类型的128位寄存器已经支持了很多架构,包括x86(SSE/SSE2/SSE4.2)、ARM(NEON)、PowerPC(VSX)、MIPS(MSA)。

x86(AVX2)支持256位长寄存器,

x86(AVX512)支持512位长寄存器。

如果编译过程中没有SIMD扩展,则选择内联的FraceB+ C++实现,代码将运行如预期,尽管它可能会慢一些

1. 寄存器类型

1.1 变长

类型说明
cv::v_uint8 and cv::v_int88 bit整数(无符号/有符号) - char
cv::v_uint16 and cv::v_int1616 bit整数(无符号/有符号) - short
cv::v_uint32 and cv::v_int3232 bit整数(无符号/有符号) - int
cv::v_uint64 and cv::v_int6464 bit整数(无符号/有符号) - int64
cv::v_float3232位浮点值(有符号)- float
cv::v_float6464位浮点值(有符号)- double

上述所有类型的确切长度(和值数量)是在编译时推导确定的,并且取决于在编译期间选择的SIMD的类型。

如果类型的确切长度很重要,则可以使用下面这些特定的固定长度的寄存器类型。

1.2 定长

128 bit寄存器类型

类型说明
cv::v_uint8x16 and cv::v_int8x1616个8 bit的整数值(无符号/有符号) - char
cv::v_uint16x8 and cv::v_int16x88个16 bit的整数值(无符号/有符号) - short
cv::v_uint32x4 and cv::v_int32x44个32 bit的整数值(无符号/有符号) - int
cv::v_uint64x2 and cv::v_int64x22个64 bit的整数值(无符号/有符号) - int64
cv::v_float32x44个32 bit的浮点数(有符号) - float
cv::v_float64x22个64 bit的浮点数(有符号) - double

256 bit寄存器类型

类型说明
cv::v_uint8x32 and cv::v_int8x3232个8 bit的整数值(无符号/有符号) - char
cv::v_uint16x16 and cv::v_int16x1616个16 bit的整数值(无符号/有符号) - short
cv::v_uint32x8 and cv::v_int32x88个32 bit的整数值(无符号/有符号) - int
cv::v_uint64x4 and cv::v_int64x44个64 bit的整数值(无符号/有符号) - int64
cv::v_float32x88个32 bit的浮点数(有符号) - float
cv::v_float64x44个64 bit的浮点数(有符号) - double

Note

目前仅为AVX2 SIMD扩展实现了256位寄存器,如果要直接使用此类型,请不要忘记检查CV_SIMD256预处理器定义:

#if CV_SIMD256
//...
#endif

512 bit寄存器类型

类型说明
cv::v_uint8x64 and cv::v_int8x6464个8 bit的整数值(无符号/有符号) - char
cv::v_uint16x32 and cv::v_int16x3232个16 bit的整数值(无符号/有符号) - short
cv::v_uint32x16 and cv::v_int32x1616个32 bit的整数值(无符号/有符号) - int
cv::v_uint64x8 and cv::v_int64x88个64 bit的整数值(无符号/有符号) - int64
cv::v_float32x1616个32 bit的浮点数(有符号) - float
cv::v_float64x88个64 bit的浮点数(有符号) - double

Note

目前仅为AVX512 SIMD扩展实现了512位寄存器,如果要直接使用此类型,请不要忘记检查CV_SIMD512预处理器定义。

cv::v_float64x2未在NEON variant中实现,如果要使用此类型,请不要忘记检查cv_SIMD128_64F预处理器定义。

2. 主要方法分类

向量构造类(Constructors)

其他的向量创建方法类(Other create methods)

内存读入操作类(Memory load operations)

扩展值的内存操作类(Memory operations with expansion of values)

存储操作类(store):在不同的平台功能上是相似的。

向量内元素排序和组合类(Value reordering)

  1. 向量元素逆序
  2. 向量左旋、右旋
  3. 两个向量交错

算术、位运算和比较运算类(Arithmetic, bitwise and comparison operations)

数据规约操作(reduce and mask)

  1. 向量中的最大值、最小值
  2. 两个向量中对应元素求差的绝对值,再全部求和。

其他数学方法类(Other math)

  1. 取绝对值
  2. 取差的绝对值
  3. 向上取整、向下取整、四舍五入
  4. 向量点积
  5. 计算a * b + c
  6. 求平方根、求平方根的倒数
  7. 计算大小, sqrt(a2 + b2)
  8. 最大值、最小值
  9. 数的加减法、乘法。

类型转换和强制转换(Conversions)

矩阵运算(Matrix operations)

  1. 矩阵乘法
  2. 矩阵a * b + c
  3. 4x4的矩阵转置

3. 方法

函数说明
&(&=)按位与,仅支持整型
!=不等于,除了64位整数以外的类型都可以用
*(*=)乘法运算,适用于16位和32位的整型和浮点型
-(-=)、+(+=)加、减法运算,适用于所有类型
/(/=)除法运算,仅适用于浮点型。
>、>=、<、<=、==比较大小,除了64位整数以外的类型都可以用
<<、>>按位左移右移、用于16、32、64位整数
=、|、|=、~位运算,仅适用于整型。

256位寄存器的读入

函数说明
v256_cleanup()
v256_load()从内存中读取若干数据,读取的元素数量,取决于数据类型大小。
所以,返回的寄存器类型也不一样。
v256_load_aligned()适用于内存对齐的情况下(SIMD256下为32字节边界,SIMD-512字节边界)。
v256_load_expand()2倍扩展读入。如果源类型数据一个是 x 位,则读入后是 2x 位。
v256_load_expand_q()4倍扩展读入。
v256_load_halves()从两个内存地址读入数据,一个内存地址读一半。
v256_load_low()只读寄存器的一半数据(前128位读满)。

256位寄存器的值设定

函数说明
v256_setall_TYPE()系列参数是一个数值,返回一个寄存器类型(比如:v_float32x8)。
v256_setzero_TYPE()系列无参数,返回一个寄存器类型(比如:v_float32x8),元素全0。

其他操作

函数说明
v_abs()取绝对值,仅用于浮点类型。
v_absdiff()取a和b的差的绝对值,用于8、16、32位整型、32、64位浮点。
v_absdiffs()加入了饱和运算的 v_absdiff(),用于8、16位整型
v_add_wrap()对于饱和运算加入不饱和的值,用于8、16位整型
v_broadcast_element()用第 i 个元素填充整个向量,用于32位整数和(s32/u32/f32)。
v_ceil()向上取整,输入一个float或者double,返回一个int。
v_check_all()检测是否全都小于0,无符号数会被强转成有符号数。
v_check_any()检查是否存在小于0的,无符号数会被强转成有符号数。
v_combine_high()把两个向量的后半部分元素合并成一个新的向量,除了64位整数都可用。
v_combine_low()把两个向量的前半部分元素合并成一个新的向量,除了64位整数都可用。
v_cvt_f32()、v_cvt_f64()转成float、float64类型
v_dotprod()向量点积,有个重载版本,加了一个数到相邻对的总和中。
v_dotprod_expand()同上,相邻结果对的和做了扩展。
v_dotprod_fast()点积函数的加速版本。
v_dotprod_expand_fast()点积函数的加速版本。
v_expand(a, b, c)把a中的元素宽度扩展,分别存到b和c中。
v_expand_high(a, b)只对a中的后(高)半部分元素做扩展,存到b中。
v_expand_low()同上。
v_extract()向量元素提取,具体看官网用法。
v_extract_n()取出向量 v 的第 i 个元素。
v_floor()向下取整,输入一个float或者double,返回一个int。
v_fma(a, b, c)返回a * b + c,仅用于浮点数和32位有符号整数。
v_interleave_pairs()元素交叉
v_interleave_quads()元素交叉
v_invsqrt()求平方根的倒数,仅用于浮点数。
v_load()读入数据,返回类型根据参数的类型而定。
v_load_aligned()v_load的对齐版本。
v_load_deinterleave(p, a, b…)解交错读入,从p读入数据,a、b…中交叉存放。
v_load_expand()以2倍扩展的方式读入数据。
v_load_expand_q()以4倍扩展的方式读入数据。
v_load_halves()从两个内存地址读入数据,一个内存地址读一半。
v_load_low()只读寄存器的一半数据(前一半)。
v_lut()
v_lut_deinterleave()
v_lut_pairs()
v_lut_quads()
v_magnitude(a, b)计算大小,返回 sqrt(a^2 + b^2),仅用于浮点数。
v_matmul()矩阵乘法。
v_matmuladd()矩阵乘法+系数
v_max()、v_min()求两个数的最大、小值,除了64位整数都可以用。
v_mul_expand()两数相乘,结果最扩展。仅用于16位整数、无符号32位整数。
v_mul_hi()两数相乘,只取结果的高位(高16位)。仅用于16位整数。
v_mul_wrap()没有饱和运算的乘法,仅用于8、16位整数。
v_muladd()与v_fma相同。
v_not_nan()
v_pack()
v_pack_b()
v_pack_store()
v_pack_triplets()
v_pack_u()
v_pack_u_store()
v_popcount()统计整数的二进制表达中 1 的个数,返回是对应的无符号整数。
v_recombine()组合来自其他两个向量的较低部分和较高部分的两个向量。
v_reduce_max()、v_reduce_min()向量中的最大、小值。除了64位整数和64位浮点数之外都可用。
v_reduce_sad()两个向量中对应元素求差的绝对值,再全部求和。除了64位整数都可用
v_reduce_sum()向量元素求和。
v_reduce_sum4()同上,但是可以同时算4个向量,结果是一个向量。
v_reinterpret_as_TYPE()系列
v_reverse()向量元素逆序。
v_rotate_left()、v_rotate_right()向量左(右)旋(1个向量、2个向量)。
v_round()元素四舍五入的结果,输入一个float或者double,返回一个int。
v_rshr()
v_rshr_pack()
v_rshr_pack_store()
v_rshr_pack_u()
v_rshr_pack_u_store()
v_scan_forward()返回向量中第一个负值的通道号(下标)。
v_select(mask, a, b)在a和b中选择元素,选法:result[i] = mask[i] ? a[i] : b[i];
v_setall_TYPE()系列
v_setzero_TYPE()系列
v_shl()
v_shr()
v_signmask()返回向量的负值掩码。
v_sqr_magnitude(a, b)计算大小,返回 sqrt(a[i]^2 + b[i]^2),仅用于浮点数。
v_sqrt()求平方根
v_store()写到内存,指针不能是对齐的。
v_store_aligned()写到内存,指针必须是对齐的。
v_store_aligned_nocache()
v_store_low()、v_store_high()存储向量的低(高)半部分到内存。
v_store_interleave(p, a, b…)向量a、b…中的元素交叉保存到从 p 开始的内存。除了64位的类型都可用。
v_sub_wrap()减法,仅用于8、16位整数。
v_transpose4x4()对4x4的矩阵做转置。
v_trunc()截断每个浮点数,输入为浮点数,输出为整数。
v_zip()交错两个向量。除了64位的类型都可用。
各个函数的vx版本功能类似。用的话再去看官方文档。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值