【SIMD】 Risc-v SIMD指令集RVV介绍

主要介绍Risc-v SIMD指令集RVV及其在性能优化方面的应用

References

算子源码

Note

  • illegal instruction:修改CSR的mstatus标志位

important concepts

VLEN (Vector Length)

  • 定义:向量寄存器的长度,表示每个寄存器可以存储的最大元素数量,通常是硬件设定的,例如 128 位、256 位或 512 位。
  • 作用:决定向量寄存器的容量和能处理的数据量。
  • 例子
    • 如果 VLEN 为 256 位且每个元素为 32 位整数,则每个寄存器最多存储 8 个元素(256 / 32 = 8)。

SLEN (Stride Length)

  • 定义:元素在内存中的步长,即两个连续元素之间的内存偏移量。
  • 作用:影响内存访问模式,特别是在访问非连续内存时,SLEN 决定了元素之间的间隔。
  • 例子
    • 假设一个向量寄存器存储 4 个元素,每个元素大小为 32 位,而 SLEN 设置为 2,这意味着每个向量元素在内存中的位置间隔为 2 个 32 位单元。

ELEN (Element Length)

  • 定义:每个向量元素的大小(单位:比特),决定了每个元素占用多少内存。
  • 作用:影响向量中每个元素的数据类型大小,在指令中用e表示,如e32。
  • 例子
    • 如果 ELEN 设置为 32 位,则每个向量元素为 32 位宽,可以是一个 32 位整数或 32 位浮点数。
    • 如果 ELEN 为 64 位,则每个元素占 64 位,适用于较大数据类型(如 64 位整数或浮点数)。

LMUL (Vector Register Grouping Factor)

  • 定义:向量寄存器的分组因子,控制每个向量寄存器内元素的数量,决定寄存器的并行度。
  • 作用:LMUL 会影响每个向量寄存器中包含的元素数量,从而影响并行性,在指令中用m表示,如m1。
  • 例子
    • LMUL = 1:每个寄存器存储最大数量的元素(假设 VLEN = 256 位,ELEN = 32 位,则每个寄存器存储 8 个元素)。
    • LMUL = 2:每个寄存器只存储 4 个元素,寄存器总数增加,适合提高并行度。
    • LMUL = 4:每个寄存器只存储 2 个元素。

VL (Vector Length Register)

  • 定义:VL 是一个寄存器,用来控制当前向量指令的长度,即当前指令能处理的元素数量。
  • 作用:在 RVV 指令中,VL 决定了向量运算的迭代次数,向量操作将执行 VL 次。
  • 例子
    • 如果 VL = 4,那么该指令将对前 4 个向量元素执行操作,用setvl(max)指令可以得到指令类型的最大元素数量,其中每个指令指定vl可处理不同数量的元素。

VTYPE (Vector Type Register)

  • 定义:VTYPE 控制向量操作的类型,如元素长度 (ELEN) 和 LMUL 的配置。
  • 作用:配置向量操作的具体参数,帮助硬件理解如何处理向量指令。
  • 例子
    • VTYPE 设置为 ELEN = 32 位,LMUL = 1,表示每个向量寄存器存储 32 位元素,且每个寄存器的并行度为 1。

Vector Mask (vmsk)

  • 定义:向量掩码用于控制哪些向量元素应该被操作,哪些应该被忽略。
  • 作用:掩码机制使得程序能够选择性地执行向量操作。
  • 例子
    • vmsk = 11110000(二进制),则只有前 4 个向量元素会被操作,后 4 个元素将被忽略。

Vector Registers (v0 - vn)

  • 定义:向量寄存器用于存储向量数据,RISC-V 定义了 v0 到 v31 的向量寄存器。
  • 作用:这些寄存器用于存储和处理向量数据,数量和大小可由硬件决定。
  • 例子
    • v0v1 可以分别存储 256 位的向量数据,适用于不同长度的数据类型。

Vector Load/Store Instructions

  • 定义:向量加载和存储指令,用于将数据从内存加载到向量寄存器,或将向量寄存器中的数据存储回内存。
  • 作用:支持各种内存访问模式,如连续或非连续访问。
  • 例子
    • vlb:加载字节数据到向量寄存器。
    • vsb:将字节数据存储回内存。

Vector Arithmetic Instructions

  • 定义:向量算术指令用于执行向量加法、减法、乘法、除法等算术运算。
  • 作用:向量算术指令在多核处理器中并行执行运算。
  • 例子
    • vadd:向量加法,执行两个向量的逐元素加法。
    • vmul:向量乘法,执行两个向量的逐元素乘法。

Vector Compare Instructions

  • 定义:向量比较指令用于比较向量中的元素,返回布尔掩码结果。
  • 作用:常用于条件判断和控制流。
  • 例子
    • vseq:判断两个向量的元素是否相等,结果返回掩码。
    • vsgt:判断向量元素是否大于另一个向量,返回布尔掩码。

Vector Reduction Instructions

  • 定义:向量归约指令用于将向量中的多个元素归约为一个单一结果,如求和、求最大值等。
  • 作用:常用于矩阵运算、图像处理等应用。
  • 例子
    • vredsum:求和,将向量中所有元素相加。
    • vredmax:求最大值,返回向量中的最大元素。

Vector Scatter/Gather Instructions

  • 定义:用于从非连续的内存地址中加载数据或将数据存储到非连续的内存地址。
  • 作用:提高对非连续内存的访问效率。
  • 例子
    • vscatter:将向量元素存储到不连续的内存位置。
    • vgather:从不连续的内存位置加载数据到向量寄存器。

Vector-Scalar Operations

  • 定义:向量与标量之间的操作,允许标量与每个向量元素进行逐一运算。
  • 作用:通过标量与向量元素的结合,处理常数数据。
  • 例子
    • vaddvi:将一个标量与向量中的每个元素相加。
    • vmulvi:将一个标量与向量中的每个元素相乘。

Vector Predication

  • 定义:根据掩码或布尔条件选择性执行向量操作。
  • 作用:通过掩码决定哪些元素进行计算,哪些跳过。
  • 例子
    • vmand:与掩码进行与运算,满足条件的元素进行计算。

Vector Tail & Masking

  • 定义:当 VL 不能完全填充向量寄存器时,通过尾部掩码控制哪些元素需要操作。
  • 作用:避免浪费计算资源,确保运算的有效性。
  • 例子
    • 如果 VL = 5,而寄存器有 8 个元素,掩码将控制只操作前 5 个元素。

Vector Unit (VU)

  • 定义:向量单元是硬件中的计算单元,负责执行向量指令。
  • 作用:处理向量计算,提高处理器的并行度。
  • 例子
    • 在支持 RVV 的处理器中,向量单元可以同时处理多个向量运算。

Note

常见使用方式

以float32类型dot计算为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void riscv_dot_prod_f32(
  const float32_t * pSrcA,
  const float32_t * pSrcB,
        uint32_t blockSize,
        float32_t * result)
{
  float32_t sum = 0.0f;

  size_t blkCnt = blockSize;
  size_t l;
  vfloat32m8_t v_A, v_B;
  vfloat32m8_t vsum;

  l = __riscv_vsetvlmax_e32m8();
  vsum = __riscv_vfmv_v_f_f32m8(0.0f, l);

  for (; (l = __riscv_vsetvl_e32m8(blkCnt)) > 0; blkCnt -= l)
  {
    v_A = __riscv_vle32_v_f32m8(pSrcA, l);
    pSrcA += l;
    v_B = __riscv_vle32_v_f32m8(pSrcB, l);
    pSrcB += l;
    vsum = __riscv_vfmacc_vv_f32m8(vsum, v_A, v_B, l);
  }
  l = __riscv_vsetvl_e32m8(1);
  vfloat32m1_t temp00 = __riscv_vfmv_v_f_f32m1(0.0f, l);
  l = __riscv_vsetvlmax_e32m8();
  temp00 = __riscv_vfredusum_vs_f32m8_f32m1(vsum, temp00, l);
  sum = __riscv_vfmv_f_s_f32m1_f32(temp00);
  *result = sum;
}
Licensed under CC BY-NC-SA 4.0
最后更新于 Feb 19, 2025 00:00 +0800
loveleaves
使用 Hugo 构建
主题 StackJimmy 设计