Page 82 - 《软件学报》2025年第9期
P. 82
韩柳彤 等: 面向 RISC-V 向量扩展的高性能算法库优化方法 3993
表 2 OpenCV 的通用内建函数类型
标量类型 128位向量类型 256位向量类型 512位向量类型 未知长度向量类型
unsigned char v_uint8x16 v_uint8x32 v_uint8x64 v_uint8
char v_int8x16 v_int8x32 v_int8x64 v_int8
unsigned short v_uint16x8 v_uint16x16 v_uint16x32 v_uint16
short v_int16x8 v_int16x16 v_int16x32 v_int16
unsigned int v_uint32x4 v_uint32x8 v_uint32x16 v_uint32
int v_int32x4 v_int32x8 v_int32x16 v_int32
unsigned long int v_uint64x2 v_uint64x4 v_uint64x8 v_uint64
long int v_int64x2 v_int64x4 v_int64x8 v_int64
_Float16 v_float16x8 v_float16x16 v_float16x32 v_float16
float v_float32x4 v_float32x8 v_float32x16 v_float32
double v_float64x2 v_float64x4 v_float64x8 v_float64
● 向量初始化与内存读写操作: v_setall, v_setzero, v_load, v_load_aligned, v_load_low, v_load_halves, v_load_
expand, v_load_expand_q, v_store, v_store_aligned, v_store_high, v_store_low 等;
● 算术、逻辑、比较与位运算操作: v_min, v_max, v_mul_expand, v_shl, v_shr 和向量类型的重载运算符 (+, –,
*, /, <<, >>, &, | , ^, ~, >, >=, <, <=, ==, !=) 等;
● 归约与掩码操作: v_reduce_min, v_reduce_max, v_reduce_sum, v_popcount, v_signmask, v_check_all,
v_check_any, v_select 等;
● 元素重排序操作: v_load_deinterleave, v_store_interleave, v_expand, v_expand_low, v_expand_high, v_pack,
v_zip, v_recombine, v_combine_low, v_combine_high, v_reverse, v_extract 等;
● 类型转换与舍入操作: v_round, v_floor, v_ceil, v_trunc, v_cvt_f32, v_cvt_f64 v_reinterpret_as_* 等;
● 矩阵运算操作: v_dotprod, v_dotprod_fast, v_dotprod_expand, v_dotprod_expand_fast, v_matmul,
v_transpose4x4 等;
● 其他计算机视觉领域的数学运算操作: v_sqrt, v_invsqrt, v_magnitude, v_sqr_magnitude, v_abs, v_absdiff,
v_absdiffs 等.
值得注意的是, 由于目标硬件平台集合对于不同操作的支持情况存在差异, 并非所有操作对于每种向量类型
均有实现, 部分向量操作可能仅支持某一个或多个向量类型.
3.1.3 通用内建函数到特定平台内建函数的映射
后文图 3 展示了通用内建函数映射到各特定平台内建函数的流程. 在编译时, 构建工具会执行目标平台检查,
其分别尝试构建特定平台的测试程序, 如果能够成功构建, 则在后续编译流程中启用对应的条件宏 (如 RISC-V 向
量扩展平台上会启用 CV_RVV), 并将向量类型和向量操作通过各个后端对于硬件抽象层接口的实现映射到特定
平台, 完成通用内建函数到平台内建函数的转换过程.
3.2 RISC-V 向量扩展与通用内建函数的兼容性
RISC-V 向量扩展与其他 SIMD 扩展的核心差异之一在于其采用了可变的向量寄存器长度. 具体而言, 与
SSE 定义了 128 位的向量寄存器、AVX2 定义了 256 位的向量寄存器不同的是, RISC-V 向量扩展中的向量寄存
器长度在指令集层面未被确定, 不同硬件的微架构被允许根据其应用场景实现不同的寄存器长度. 与之类似的,
在 ARM 平台上, SVE (scalable vector extensions) 及 SVE2 也采用了类似的可扩展向量机制.
OpenCV 曾试图将 RISC-V 向量扩展视为固定长度的 SIMD 扩展, 从而兼容现有硬件抽象层的设计. 考虑到对
于应用处理器, RISC-V 向量扩展的最小向量寄存器长度为 128 位, OpenCV 将其作为该平台上的向量寄存器标准.
显而易见的, 以可变长向量扩展的最小实现作为标准将不可避免地浪费硬件寄存器资源: 尽管指令能够在拥有不
同向量寄存器长度的 RISC-V 设备上正确执行, 但在拥有更长向量寄存器长度的硬件设备上, 向量寄存器中高于
128 位的部分将不会被使用, 无法充分利用硬件资源, 影响其性能表现.

