HPC101-lab2.5 rvv intrinsics实现整数乘法

  1. 实验文档参考此处
  2. 实验代码如下:
size_t vl_max = __riscv_vsetvlmax_e8m1();
    int stride = 4;

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            int32_t sum = 0;
            for (int kk = 0; kk < k * stride; kk += vl_max) {
                size_t current_vl = __riscv_vsetvl_e8m1(k * stride - kk);
                // 跳步加载
                vuint8m1_t va = __riscv_vlse8_v_u8m1(&A[i * k * stride + kk], 1, current_vl);
                vint8m1_t vb = __riscv_vlse8_v_i8m1(&B[j * k * stride + kk], 1, current_vl);
                vint16m2_t vprod_ext1 =         __riscv_vwmulsu_vv_i16m2(vb, va, current_vl);
                vint32m4_t vprod_ext =  __riscv_vsext_vf2_i32m4(vprod_ext1, current_vl);
                // 此处注意,为了测试时间所以外层有1000次循环,如果需要printf的话需要修改打印次数
//              if(i == 0 && j == 0) {
//                      printf("%d\n", vl_max);
//               print_vector(vprod_ext, current_vl);
//              }
                // 规约求和
                vint32m1_t v_zero = __riscv_vmv_v_x_i32m1(0, current_vl);
                vint32m1_t v_sum = __riscv_vredsum_vs_i32m4_i32m1(vprod_ext, v_zero, current_vl);
                sum += __riscv_vmv_x_s_i32m1_i32(v_sum);
            }
            C[i * n + j] = sum;
        }
    }
  1. 在开发过程中我出现bug的两处:
  • 没有考虑到A和B矩阵的列数是K * 4,也即naive实现里面k * 4作为循环跳出条件的原因。
  • 没有考虑到lse这种加载方式中第二个参数stride的作用,造成了重复读取(设为0)。
  1. 同时推荐使用printf的方式对rvv用到的一些向量进行打印。

  2. 测试结果:
    Baseline: 34205 ms
    Optimized: 10575 ms
    Speedup: 3.23452x

  3. 使用直接load的方式加载
    测试结果:
    Baseline: 34222 ms
    Optimized: 4713 ms
    Speedup: 7.26119x
    证明对于连续数据使用不带stride的读写会显著优于带stride的读写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值