3. 向量减法运算
任务目标
实现两个长度相同的向量逐元素相减,并将结果存储到目标向量中。本案例基于RISC-V P900系列处理器,使用其向量扩展指令集完成运算,重点演示向量加载、向量减法和向量存储的基本流程。
环境依赖
本案例代码面向RISC-V向量扩展(RVV)指令集,需要以下环境支持:
- 支持RVV 1.0的RISC-V交叉编译器(如riscv64-unknown-elf-gcc,需开启向量扩展选项)
- P900系列处理器或对应模拟器(如QEMU with vector support)
核心代码
#include <riscv_vector.h>
#include <stdint.h>
#include <stddef.h>
#define VLEN 128 // 向量长度(位)
// 向量减法函数:dst[i] = src1[i] - src2[i]
void vector_sub_int32(int32_t *dst, const int32_t *src1, const int32_t *src2, size_t n) {
size_t i = 0;
// 每轮处理VLMAX个元素(由硬件vlmax决定)
while (i < n) {
size_t vl = vsetvl_e32m1(n - i); // 设置向量长度,处理剩余元素
vint32m1_t v1 = vle32_v_i32m1(&src1[i], vl); // 加载src1
vint32m1_t v2 = vle32_v_i32m1(&src2[i], vl); // 加载src2
vint32m1_t vd = vsub_vv_i32m1(v1, v2, vl); // 逐元素相减
vse32_v_i32m1(&dst[i], vd, vl); // 存储结果
i += vl;
}
}
// 测试入口
#define N 8
int32_t a[N] = {10, 20, 30, 40, 50, 60, 70, 80};
int32_t b[N] = {1, 2, 3, 4, 5, 6, 7, 8};
int32_t c[N];
int main() {
vector_sub_int32(c, a, b, N);
// 验证结果(预期:9, 18, 27, 36, 45, 54, 63, 72)
for (int i = 0; i < N; i++) {
if (c[i] != a[i] - b[i]) {
return 1; // 验证失败
}
}
return 0; // 验证通过
}
编译与运行
# 编译(假设使用支持RVV的riscv64工具链)
riscv64-unknown-elf-gcc -march=rv64gcv -mabi=lp64d -O2 -o vector_sub vector_sub.c
# 在P900模拟器或QEMU中运行
qemu-riscv64 -cpu rv64gcv ./vector_sub
# 查看退出码(0表示验证通过)
echo $?
验证方法
程序内置了自校验逻辑:计算完成后逐元素检查结果是否等于 a[i] - b[i]。若所有元素正确,main函数返回0;否则返回1。通过检查程序退出码即可判定执行是否成功。
关键说明
vsetvl_e32m1根据硬件最大向量长度自动计算每次处理的元素个数,循环直至处理完所有元素- 本案例使用
int32_t类型演示,如需其他数据类型(如int16、float),只需替换对应的加载/存储/运算内建函数 - P900处理器支持RVV 1.0标准,代码中使用的内建函数均符合该规范