RVV 也许没有想象的那么好

引言 RISC-V 作为一个新兴的 ISA ,从前辈的错误中吸取了很多教训,同时提出了一些非常有吸引力的设计,被我的很多朋友喜爱。RISC-V 在我所接触的圈子里经常是“现代”与“优雅”的代名词,而它的向量扩展(RVV)也常常被冠以同等的荣耀,尽管几乎没人摸过有 RVV 的实机,也很少有人真的使用 RVV 进行编程过——这是当然的,毕竟 RVV Intrinsic 的编译器实现还很不完全。在把玩了一段时间 RVV 后,我感到它并没有像很多资料所推销的那么好。 我 SIMD 编程的经验并不多,Vector 架构更是在此前没有接触过。在批评一个自己不甚熟悉的事物时我总是感到惶恐的,还望轻喷。 RVV 是怎么设计的 与常见的 SIMD 架构不同,RVV 的向量寄存器长度是可变的。这是指不同的芯片(准确地说是 hardware thread 或者 hart)可以拥有不同长度的向量寄存器,并且我们可以动态改变参与运算的长度。要做到这一点,需要程序在运行时通过某些指令获取和设置长度参数。不仅如此,RVV 的运算只区分 vector 与 vector 的运算 / vector 与 scalar 的运算,以及有无符号,并不区分元素长度,这意味着元素长度也是一个动态设置的参数。此外,RVV 允许我们只使用向量寄存器的一部分,或是把多个向量寄存器并起来使用,这又需要另一个动态参数。具体来说,一个向量寄存器的类型主要由以下几个参数共同决定: VLEN,向量寄存器的长度 vl,一个 CSR(Control and Status Register),控制运算中实际用到的元素个数 vtype,一个 CSR ,包括这几个部分: vill,表示 vtype 设置是否合法 vma/vta,控制被 masked-off 的元素和尾部的元素的运算行为 vsew,控制单个元素的长度,我们用 SEW = 8 | 16 | 32 | 64 代表它的值 vlmul,控制一个操作使用多少个寄存器,我们用 LMUL = 1/8 | 1/4 | 1/2 | 1 | 2 | 4 | 8 代表它的值 值得一提的是这个 LMUL。当它小于 1,比如说 1/2 的时候,我们就只启用寄存器的一半长度。当它大于 1,比如说 8 的时候,我们就会把 8 个寄存器并起来一起用。...

2022-02-27 · QuarticCat