[libre-riscv-dev] SV Prefix questions
Jacob Lifshay
programmerjake at gmail.com
Tue Jun 25 21:48:37 BST 2019
On Tue, Jun 25, 2019, 08:29 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:
> https://libre-riscv.org/simple_v_extension/sv_prefix_proposal/discussion/
>
> jacob: the compiler knows MAXVL at compile-time, however the engine does
> not, and must be told what it is. then, loops like the DAXPY one from
> "SIMD Considered Harmful" will work (even on SV):
>
> # a0 is n, a1 is pointer to x[0], a2 is pointer to y[0], fa0 is a
> 0: li t0, 2<<25
> 4: vsetdcfg t0 # enable 2 64b Fl.Pt. registers
> loop:
> 8: setvl t0, a0 # vl = t0 = min(mvl, n)
> c: vld v0, a1 # load vector x
> 10: slli t1, t0, 3 # t1 = vl * 8 (in bytes)
> 14: vld v1, a2 # load vector y
> 18: add a1, a1, t1 # increment pointer to x by vl*8
> 1c: vfmadd v1, v0, fa0, v1 # v1 += v0 * fa0 (y = a * x + y)
> 20: sub a0, a0, t0 # n -= vl (t0)
> 24: vst v1, a2 # store Y
> 28: add a2, a2, t1 # increment pointer to y by vl*8
> 2c: bnez a0, loop # repeat if n != 0
> 30: ret # return
>
> in the above, let's say that MAXVL is 8 and a0 is 1,000. SETVL goes "vl =
> t0 = min(8, 1000)" and sets both vl and t0 to 8 as a result. clearly the
> next loop will do the same.
>
> only when a0 starts to drop *below* 8 will both vl and t0 be set to below 8
> (MVL). in RVV, the implementor is allowed to start "throttling" by
> changing VL to 1/2 the value - this to prevent the "concertina" effect,
> apparently:
> https://en.wikipedia.org/wiki/Accordion_effect
>
> the thing is: i do not believe that the rules that you set would allow the
> same behaviour. i did try creating something like it, a year ago:
> everything i could think of required either 2 to 3 additional instructions
> (inside the loop) because there was no way to get the same "vl = rd =
> min(rs, MVL)" behaviour as a single opcode, or it required a THIRD extra
> argument to SETVL - addition of the MAXVL value as a parameter (a constant
> or an immediate).
>
Just use setvli as the base instruction, the immediate has 11 bits --
plenty for MAXVL:
https://github.com/riscv/riscv-v-spec/blob/master/vcfg-format.adoc
if we don't want to conflict with the V extension, we could add a custom 32
or 48-bit instruction.
>
> that in turn would require the addition of an extra opcode, which is "off
> the table" as a hard requirement for SV.
>
it may be off the table for SVorig, but I think we should add it to
SVprefix -- it removes one CSR and reduces a common instruction sequence to
1 instruction rather than 2.
For SVorig, adding a MAXVL CSR seems like the only option.
>
> setting alternative rules, it's *essential* to come up with working demo
> pseudo-assembly. after several weeks of thinking about this i gave up and
> decided to go with something that was very close to RVV. this not just to
> save time and effort at the *design* phase, it's also to save on conceptual
> explanations and also on compiler development.
>
The semantics I had defined before you removed the setvl instruction from
SVprefix (putting a note that setvl was considered for removal would have
been better, since that way people could still read the definition) are the
same as the V extension when rs1 is not x0 except that I had the MAXVL <
rs1 < MAXVL * 2 case set VL to floor(rs1 / 2) instead of ceil(rs1 / 2), I
think ceil is a better option. MAXVL is the immediate operand. When rs1 is
x0, the instruction loads VL with MAXVL. The instruction I defined happened
to share the same mnemonic as the V extension's setvl, but is a separate
instruction.
Jacob
More information about the libre-riscv-dev
mailing list