【RISCV指令集手册】向量扩展v1.0
概述
从rvv 0.9说起
此前写过向量扩展0.9的阅读记录,三年已过,本以为不再参与RVV的相关开发,奈何造化弄人,旧业重操,真就世事难料呀。
总的来说1.0版本相比0.9版本的扩充了较多内容,但大部分为指令功能的扩充,指令编码、向量的运行机制等几乎没有变化,也就是说0.9版本的工具链可以兼容1.0的共性的指令。
KGback:RSIC-V——指令集spec阅读笔记——向量扩展0.9
主要不同
本文主要针对1.0新的版本作阅读记录,与0.9相同功能将不再赘述,若有所区别将在下文中体现。
1.0增加了LMUL为1/8, 1/4, 1/2
指令集理解Tricks
指令集手册中部分指令功能晦涩难懂,此时可参考指令集模拟器Spike中对于该指令的实现,该模拟器是riscv官方发布的golden模型。
Spike Github仓库
CPU RVV计算核实现一览
对于 RISC-V Vector 指令的应用现有 NX27V 芯片、C906 芯片、SG2042 芯片、siFive Performance 系列芯片等,其中 NX27V 芯片、siFive Performance 系列芯片支持 RISC-V Vector 1.0 版本。
玄铁C906/C920等
C906、SG2042 芯片支持的是 RISC-V Vector SPEC 0.7.1版本,与现在上游编译器 RISC-V Vector SPEC 1.0 版本不兼容。现社区有 RISC-V Vector rollback 脚本,可将 RISC-V Vector Extension v1.0 的汇编代码转换为 v0.7.1,因此上游编译器代码编出的 .s 中的 RVV SPEC v1.0 版本指令可通过此脚本转换成 RISC-V Vector SPEC v0.7.1 标准指令,这样就可以将代码最终执行在 C906、SG2042 芯片上1。
C920是玄铁首次加入v1.0内容的处理器。
Ara@苏黎世联邦理工大学
开源
Github链接
VPU@Barcelona Supercomputing Center
EPAC1.0 RVV Vector tile
特征:
- VLEN为16384
- 轻量化的乱序引擎允许访存和算术操作重叠执行
相关研究:
- Luca Valente, A Vector Processing Unit implementation for RISC-V Vector Extension: Functional Verification and Assertions on submodules
本文描述的加速器兼容于rvv0.7.1,BSC团队应是开发了多款RVV加速器。 - Functional Verification of a RISC-V Vector Accelerator
设计兼容于rvv0.7.1,该文章应是前者论文的验证环境。 - Vectorizing Pytorch for RISC-V RVV
在该SoC的硬件平台上移植了Pytorch。
vrgather指令的设计可参考该工程:
KGback:Luca Valente论文阅读
Arrow
Arrow: A RISC-V Vector Accelerator for Machine Learning Inference
rvv0.9
Github链接
@misc{assir2021arrowriscvvectoraccelerator,
title={Arrow: A RISC-V Vector Accelerator for Machine Learning Inference},
author={Imad Al Assir and Mohamad El Iskandarani and Hadi Rayan Al Sandid and Mazen A. R. Saghir},
year={2021},
eprint={2107.07169},
archivePrefix={arXiv},
primaryClass={cs.AR},
url={https://arxiv.org/abs/2107.07169},
}
Ava
rvv0.8,VLEN=32,4年未更新
Github链接
Expanding a RISC-V Processor with Vector Instructions for Accelerating Machine Learning | British Computer Society Open Source Specialists
Github上的一些开源工程
Nikola2444/RISC-V-vector-processor
2年未更新
Nikola2444/RISC-V-vector-processor
移植了四条permutation指令:
vslideup.{type}, type = (vx, vi)
vslidedown.{type}, type = (vx, vi)
vslide1up.vx
vslide1down.vx
译码通过状态机实现(v_cu.sv:slide_op = current_state == SLIDE)
RVV编译器进展
指令编译和自动矢量化参考该文1
应用程序的支持
参考链接
How are vector instructions implemented in RISC-V
Pytorch的支持
机器学习库的支持
GGML
GGML由C语言编写,相当于python中pytorch、tensorflow库等
GGML@Github
矩阵转置
FPROX@substack: Transposing a Matrix using RISC-V Vector
softmax
FPROX@substack: Implementing Softmax using RISC-V Vector
Github: rvv实现的softmax参考代码
图像处理的支持
Transformer模型的支持
llama.cpp利用rvv在Sifive和Qemu模拟器上的运行
KGback:llama.cpp在Qemu-riscv64向量扩展指令下的部署
在TH1520上运行llama-7b
Run LLaMA 7B int4 model onLicheePi4A (TH1520, 4xC910@2.0G), 6s/token
Github上该实验的讨论:RISC-V (TH1520&D1) benchmark and hack for <1GB DDR device
向量扩展的相关概念
tail元素
假设VLEN=32,LMUL=2,SEW=16,那么这条指令需要操作4个元素。如果vstart设置为1,vl设置为2,那这些概念对应的分别是如图2所示。
Permutation指令
排列指令,用于在向量寄存器中移动元素,0.9版本和1.0版本均有该扩展。
Move指令
滑动指令
滑动指令如下:
vslideup.vx vd, vs2, rs1, vm
vslideup.vi vd, vs2, uimm, vm
vslidedown.vx vd, vs2, rs1, vm
vslidedown.vi vd, vs2, uimm, vm
vslide1up.vx vd, vs2, rs1, vm
vfslide1up.vf vd, vs2, rs1, vm
vslide1down.vx vd, vs2, rs1, vm
vfslide1down.vf vd, vs2, rs1, vm
全排序指令
全排序指令总共如下:
vrgather.vv vd, vs2, vs1, vm
vrgatherei16.vv vd, vs2, vs1, vm
vrgather.vx vd, vs2, rs1, vm
vrgather.vi vd, vs2, uimm, vm
vrgather的指令功能如下:
vs1中的元素值作为索引,将vs2中该索引的元素赋值给vd;
vrgatherei16.vv和vrgather.vv的区别是无论SEW是多少,vs1只取16bit数。16bit足够向量中的索引最大值(LMUL=8, SEW=8-bit, VLEN=65536)
如下图3所示:
压缩排列指令
vcompress指令根据vs1的值作为掩码,将vs2中的数据复制到vd中。
一般用于数据压缩,将非零数据重新整合排列。
vcompress硬件实现的难点
vd中除第一个元素外所有元素的位置都可能被其他元素位置影响,所以执行单元设计的会变得比较复杂4
当LMUL>1时,执行单元不能提前知道具体压缩位置,但却需要支持跨越向量寄存器的所有元素指向结果元素的移动,执行部件会更加复杂
vcompress的硬件实现方法
参考链接:
积小流哥@CSDN:<RVV设计的艺术> vcompress指令实现电路
遍历法
通过对源操作数最低位置一个一个的判断是否有效,来将源元素压缩堆放在结果向量的最低元素位置,依赖的就是压缩的顺序性。
参考文献
【精华文章系列】第一期:RISC-V Vector概述 ↩︎ ↩︎
Francis Blog:riscv-vector ↩︎
RISC-V Vector Extension in a Nutshell (Part 4): permute operations ↩︎
专利:Risc-v向量压缩乱序执行的实现方法及装置 ↩︎