中心的在读硕士研究生张尹同学今年夏天成功申请并参与了GSoC(Google Summer of Code)的一个开源贡献项目OptimizeOpenCV for RISC-V,在该项目中,他为OpenCV添加了RISC-V后端支持和基于RISC-V向量扩展的优化。该项目代码现已正式进入OpenCV官方开源代码仓库,之后会作为一个新特性与OpenCV-4.5.1版本一起发布。
项目简介
OpenCV在其硬件加速层(HAL,Hardware Acceleration Layer)提供了一套OpenCV内部通用的向量系统,叫做OpenCV Wide Universal Intrinsics,这个向量系统为前端的算法实现提供了可直接调用的向量数据类型和各种向量计算操作的接口等。这套向量系统的优势在于,它为前端程序员提供了统一的向量数据类型与向量操作接口,而这些向量数据类型与向量操作在编译时会自动地被转换为当前目标平台所支持的SIMD或向量体系结构的指令,从而使得OpenCV在任何支持SIMD或向量指令的硬件平台上都能获得指令集层面的数据并行加速。
先前的OpenCV中,通用向量系统(Wide Universal Intrinsics)已经获得了基于x86平台的SSE、AVX、AVX2、AVX512指令集,基于ARM平台的NEON指令集,基于IBM的POWER平台的VSX指令集,和基于MIPS平台的MSA指令集等后端支持。本次GSoC项目的目标是为Wide Universal Intrinsics实现近期非常火热的RISC-V指令集及其向量扩展(RVV)的支持,从而使OpenCV在RISC-V平台上也能获得向量加速。
RISC-V向量扩展(RVV)是RISC-V指令集的标准扩展模块之一。它主要在RISC-V基础指令集模块上添加了向量寄存器和各类向量指令,使得用户可以使用向量体系结构来优化和加速程序代码。虽然目前RISC-V向量扩展规范尚属于草案阶段,但由于其简洁而优雅的设计,该向量扩展已经获得了业界的广泛关注。
Intrinsic一般是指⾼级编程语言中的低级汇编语言的接口。大部分SIMD或向量指令集都有自己的native intrinsics。RISC-V向量扩展(RVV)也有一套定义在C/C++中的native intrinsics接口,这也是实现该项目的主要途径。
实现
实现主要分为两个部分:
-
首先要在OpenCV的编译选项中添加RISC-V(RVV)后端的信息,并使用cmake配置文件为OpenCV指定交叉编译的编译器、链接器与编译选项,使OpenCV能被成功编译至RISC-V目标平台。
-
然后再使用RISC-V向量扩展的native intrinsic,为Wide Universal Intrinsics添加一个新版本的实现,使得Wide Universal Intrinsics中为前端给出的向量类型与向量操作接口都能被编译生成RISC-V向量指令。
构建与测试
由于目前暂时没有支持RISC-V向量扩展的硬件设备(开发板),该项目的构建与测试使用RISC-V GNU工具链和PLCT实验室开发的rvv-llvm进行交叉编译,并在QEMU模拟器上运行。
OS: ubuntu:18.04
①依赖安装
apt-getupdateapt-getinstall gcc g++ git make cmake python python3 gcc-multilib vim autoconfautomake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawkbuild-essential bison flex texinfo gperf libtool patchutils bc zlib1g-devlibexpat-dev pkg-config libglib2.0-dev
②构建RISC-VGNU工具链和QEMU模拟器
git clonehttps://github.com/riscv/riscv-gnu-toolchain.git -b rvv-intrinsiccdriscv-gnu-toolchaingitsubmodule update –init –recursive./configure–prefix=/opt/RISCV –with-arch=rv64gcv_zfh –with-abi=lp64dmakelinux build-qemu -j$(nproc)
③构建RISC-V版本的OpenCV
git clonehttps://github.com/opencv/opencv.gitcd opencvmkdirbuild && cd buildcmake -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/riscv64-gcc.toolchain.cmake../make-j$(nproc)
④准确性测试
/opt/RISCV/bin/qemu-riscv64-cpu rv64,x-v=true opencv/build/bin/opencv_test_core–gtest_filter=“hal*”
⑤测试结果
当前版本通过了OpenCV自带测试集中所有的硬件加速层测试,并通过了11000+的OpenCV核心测试(占总测试用例的99.8%)。
下一步工作
后续张尹同学会持续完善这个项目,进一步修复有缺陷的测试用例,并进行性能测试与性能优化。
参考文献与相关链接
-
Pull Request of the Implementation:
-
Wide Universal Intrinsic:
https://docs.opencv.org/master/df/d91/group__core__hal__intrin.html
-
OpenCV official repository:
-
RISC-V ISA specification:
-
RISC-V “V” extension specification:
-
RVV Intrinsic specification:
-
RISC-V GNU toolchain:
-
Rvv-llvm from PLCT Group:
-
In-memory Issue details:
-
C910 implementation for WUI: