opencv之SIMD
数据类型,例如cv::v_int8x16 表示int8_t的基本数据,16个。即类型在前,数量在后。
CV_SIMD_WIDTH是一个宏定义,用于表示在OpenCV中使用的向量化数据类型的宽度。它表示一个向量中包含的元素数量。
基本数据类型
cv::v_uint8 /cv::v_int8
cv::v_uint16 /cv::v_int6
cv::v_uint32 /cv::v_int32
cv::v_uint64 /cv::v_int64
cv::v_float32
cv::v_float64
根据寄存器位数来分类,128位:
cv::v_uint8x16/cv::v_int8x16
cv::v_uint16x8/cv::v_int16x8
cv::v_uint32x4/cv::v_int32x4
cv::v_uint64x2/cv::v_int64x2
cv::v_float32x4
cv::v_float64x2
根据寄存器位数来分类,256位:(需要注意的是 要判断是否满足512bit的情况 例如CV_SIMD256)
cv::v_uint8x32/cv::v_int8x32
cv::v_uint16x16/cv::v_int16x16
cv::v_uint32x8/cv::v_int32x8
cv::v_uint64x4/cv::v_int64x4
cv::v_float64x4
初始化
变量置零可以使用
v_uint8x16 cv::v_setzero_u8 ()
v_int8x16 cv::v_setzero_s8 ()
v_uint16x8 cv::v_setzero_u16 ()
v_int16x8 cv::v_setzero_s16 ()
v_float32x4 cv::v_setzero_f32 ()
v_float64x2 cv::v_setzero_f64 ()
v_uint8x32 cv::v256_setzero_u8 ()
v_int8x32 cv::v256_setzero_s8 ()
v_uint16x32 cv::v512_setzero_u16 ()
v_int16x32 cv::v512_setzero_s16 ()
上面函数的后缀类型可以修改
设置特定的初始值可以用下列函数
v_uint8x16 cv::v_setall_u8 (uchar val)
v_int8x16 cv::v_setall_s8 (schar val)
v_uint16x8 cv::v_setall_u16 (ushort val)
v_int16x8 cv::v_setall_s16 (short val)
v_uint32x4 cv::v_setall_u32 (unsigned val)
v_int32x4 cv::v_setall_s32 (int val)
v_uint8x32 cv::v256_setall_u8 (uchar val)
v_int8x32 cv::v256_setall_s8 (schar val)
v_uint8x64 cv::v512_setall_u8 (uchar val)
v_int8x64 cv::v512_setall_s8 (schar val)
类型转换
类型转换可以使用下面系列函数
v_reinterpret_as_s8
v_reinterpret_as_u8
v_reinterpret_as_s16
v_reinterpret_as_u16
cv::vx_load
是一个通用的向量加载函数,潜在的意思是加载尽可能大的数据
cv::v_load
是一个特定于OpenCV向量化数据类型的加载函数。它用于加载特定长度的向量数据,该长度由向量化数据类型的宽度(CV_SIMD_WIDTH
)决定
下面是一个求和的示例
int add_opencv(uint8_t* data, int wid, int hei) { int total = 0; int size = wid * hei; //CV_SIMD_WIDTH // 使用128位寄存器进行SIMD计算 cv::v_int8x16 sum =cv::v_setzero_s8();// _mm_setzero_si128(); // 每次处理16个元素(8位) for (int i = 0; i < size; i += 16) { // 从内存加载16个元素到128位寄存器 cv::v_int8x16 cur=cv::v_load((const int8_t*)(data+i)); // 求和 sum = cv::v_add_wrap(sum, cur); } total=cv::v_reduce_sum(sum); // 处理剩余的元素(不足16个) for (int i = size - (size % 16); i < size; ++i) { total += data[i]; } return total; }