OpenCV - Universal intrinsics 统一指令集
文章目录
- 0. OpenCV
- 0.0 详细说明
- 1. 寄存器类型
- 1.1 变长
- 1.2 定长
- 2. 主要方法分类
- 3. 方法
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_int8 | 8 bit整数(无符号/有符号) - char |
cv::v_uint16 and cv::v_int16 | 16 bit整数(无符号/有符号) - short |
cv::v_uint32 and cv::v_int32 | 32 bit整数(无符号/有符号) - int |
cv::v_uint64 and cv::v_int64 | 64 bit整数(无符号/有符号) - int64 |
cv::v_float32 | 32位浮点值(有符号)- float |
cv::v_float64 | 64位浮点值(有符号)- double |
上述所有类型的确切长度(和值数量)是在编译时推导确定的,并且取决于在编译期间选择的SIMD的类型。
如果类型的确切长度很重要,则可以使用下面这些特定的固定长度的寄存器类型。
1.2 定长
128 bit寄存器类型
类型 | 说明 |
---|---|
cv::v_uint8x16 and cv::v_int8x16 | 16个8 bit的整数值(无符号/有符号) - char |
cv::v_uint16x8 and cv::v_int16x8 | 8个16 bit的整数值(无符号/有符号) - short |
cv::v_uint32x4 and cv::v_int32x4 | 4个32 bit的整数值(无符号/有符号) - int |
cv::v_uint64x2 and cv::v_int64x2 | 2个64 bit的整数值(无符号/有符号) - int64 |
cv::v_float32x4 | 4个32 bit的浮点数(有符号) - float |
cv::v_float64x2 | 2个64 bit的浮点数(有符号) - double |
256 bit寄存器类型
类型 | 说明 |
---|---|
cv::v_uint8x32 and cv::v_int8x32 | 32个8 bit的整数值(无符号/有符号) - char |
cv::v_uint16x16 and cv::v_int16x16 | 16个16 bit的整数值(无符号/有符号) - short |
cv::v_uint32x8 and cv::v_int32x8 | 8个32 bit的整数值(无符号/有符号) - int |
cv::v_uint64x4 and cv::v_int64x4 | 4个64 bit的整数值(无符号/有符号) - int64 |
cv::v_float32x8 | 8个32 bit的浮点数(有符号) - float |
cv::v_float64x4 | 4个64 bit的浮点数(有符号) - double |
Note
目前仅为AVX2 SIMD扩展实现了256位寄存器,如果要直接使用此类型,请不要忘记检查CV_SIMD256预处理器定义:
#if CV_SIMD256
//...
#endif
512 bit寄存器类型
类型 | 说明 |
---|---|
cv::v_uint8x64 and cv::v_int8x64 | 64个8 bit的整数值(无符号/有符号) - char |
cv::v_uint16x32 and cv::v_int16x32 | 32个16 bit的整数值(无符号/有符号) - short |
cv::v_uint32x16 and cv::v_int32x16 | 16个32 bit的整数值(无符号/有符号) - int |
cv::v_uint64x8 and cv::v_int64x8 | 8个64 bit的整数值(无符号/有符号) - int64 |
cv::v_float32x16 | 16个32 bit的浮点数(有符号) - float |
cv::v_float64x8 | 8个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)
- 向量元素逆序
- 向量左旋、右旋
- 两个向量交错
算术、位运算和比较运算类(Arithmetic, bitwise and comparison operations)
数据规约操作(reduce and mask)
- 向量中的最大值、最小值
- 两个向量中对应元素求差的绝对值,再全部求和。
其他数学方法类(Other math)
- 取绝对值
- 取差的绝对值
- 向上取整、向下取整、四舍五入
- 向量点积
- 计算a * b + c
- 求平方根、求平方根的倒数
- 计算大小, sqrt(a2 + b2)
- 最大值、最小值
- 数的加减法、乘法。
类型转换和强制转换(Conversions)
矩阵运算(Matrix operations)
- 矩阵乘法
- 矩阵a * b + c
- 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版本功能类似。 | 用的话再去看官方文档。 |
OpenCV - Universal intrinsics 统一指令集相关推荐
- 【opencv 450 core】使用统一向量指令(Universal Intrinsics)对代码进行矢量化
Vectorizing your code using Universal Intrinsics 使用 Universal Intrinsics 对代码进行矢量化 Goal 本教程的目标是提供使用通用 ...
- 统一指令集架构的思考
处理器技术是通信行业的基础,也关系到国家基础信息安全,"棱镜"事件就折射出信息安全的挑战. 去年工信部召集国内企业和科研机构商议统一国内指令集,从而集中建立自主处理器生态体系,这也 ...
- OpenCV算法加速(2)使用SIMD指令集(MMX、SSE、AVX)和MIPP实现视觉算法优化
一.概述 很多人觉得OpenCV速度比较慢,其实提升OpenCV运行速度,最常见的就是重新编译OpenCV,添加各种指令集优化支持. SIMD(Single Instruction Multiple ...
- C/C++指令集介绍以及优化(主要针对SSE优化)
前言:最近在做一些OpenCV的优化相关的东西,发现OpenCV现在的执行效率很高的原因一部分是来自于底层的优化,比如指令集优化,但是一直没找到比较系统性的关于CPU指令集优化的文章或者是书籍,于是自 ...
- Opencv学习笔记之OpenCV介绍
一. OpenCV介绍 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 ...
- 第一章之OpenCV安装
opencv 安装 一.地址 opencv官网 opencv Github 官方安装流程 二.概述 opencv有两种安装方式:1.根据自己的平台选择官方编译好的版本:2.下载源码自己编译. 三.预编 ...
- OpenCV各版本差异
Opencv2标志着opencv革命性的改变,Opencv2带来了全新的C++接口,将Opencv的能力无限放大.在2.0时代,opencv增加了新的平台支持,包括iOS和Android,通过CUDA ...
- OpenCV各版本差异与演化,从1.x到4.0
最近因项目需要,得把OpenCV捡起来,登录OpenCV官网,竟然发现release了4.0.0-beata版本,所以借此机会,查阅资料,了解下OpenCV各版本的差异及其演化过程,形成了以下几点认识 ...
- OpenCV程序效率优化方法1
OpenCV程序效率优化方法 使用指针方法遍历像素点 OpenCV中图像的存储对象为Mat类,该类提供了多种方式访问像素的的值.一般来说分为以at方法类与ptr指针的方式访问,相较之下使用指针ptr的 ...
最新文章
- 卷积转换为矩阵运算中填充数的计算-GEMM
- python用二分法求平方根_Python使用二分法求平方根的简单示例
- Java虚拟机学习集锦是我攒来的,带你碾压面试官!
- Bailian3671 字符串排序【排序】
- 2017.9.6.语文
- 计算机专业英语第五章ppt,计算机专业英语课件5.ppt
- Activity launchMode
- DVWA之SQL注入代码审计
- Android反编译工具总结
- 计算机室教学控制软件,管鲍多媒体电子教室 电脑教学软件 广播教学软件 机房控制软件...
- win10升级助手_微软官网win10下载_win10教程
- 用计算机弹清明上河图谱,一篇文章让你看懂《清明上河图》中的所有细节
- openwrt中luci学习笔记
- 简述T568A和T568B的区别
- 《最伟大的作品》,解密周杰伦新专辑背后的数据密码
- Idea构建异常---Could not parse metadata xx/xx/maven-metadata-local.xml-删除文件解决不掉---SpringCloud工作笔记176
- 19年电赛经验总结-应该如何准备电赛
- Android 购物车的简单实现
- mysql grant all_mysql用户授权之GRANT ALL PRIVILEGES用法举例
- 面向对象系列教材 (一)- Java中的类和对象