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标准,代码中使用的内建函数均符合该规范