clarify
[libreriscv.git] / simple_v_extension / simple_v_chennai_2018.tex
1 \documentclass[slidestop]{beamer}
2 \usepackage{beamerthemesplit}
3 \usepackage{graphics}
4 \usepackage{pstricks}
5
6 \title{Simple-V RISC-V Extension for Vectorisation and SIMD}
7 \author{Luke Kenneth Casson Leighton}
8
9
10 \begin{document}
11
12 \frame{
13 \begin{center}
14 \huge{Simple-V RISC-V Parallelism Abstraction Extension}\\
15 \vspace{32pt}
16 \Large{Flexible Vectorisation}\\
17 \Large{(aka not so Simple-V?)}\\
18 \Large{(aka A Parallelism API for the RISC-V ISA)}\\
19 \vspace{24pt}
20 \Large{[proposed for] Chennai 9th RISC-V Workshop}\\
21 \vspace{16pt}
22 \large{\today}
23 \end{center}
24 }
25
26
27 \frame{\frametitle{Credits and Acknowledgements}
28
29 \begin{itemize}
30 \item The Designers of RISC-V\vspace{15pt}
31 \item The RVV Working Group and contributors\vspace{15pt}
32 \item Allen Baum, Jacob Bachmeyer, Xan Phung, Chuanhua Chang,\\
33 Guy Lemurieux, Jonathan Neuschafer, Roger Brussee,
34 and others\vspace{15pt}
35 \item ISA-Dev Group Members\vspace{10pt}
36 \end{itemize}
37 }
38
39
40 \frame{\frametitle{Quick refresher on SIMD}
41
42 \begin{itemize}
43 \item SIMD very easy to implement (and very seductive)\vspace{8pt}
44 \item Parallelism is in the ALU\vspace{8pt}
45 \item Zero-to-Negligeable impact for rest of core\vspace{8pt}
46 \end{itemize}
47 Where SIMD Goes Wrong:\vspace{10pt}
48 \begin{itemize}
49 \item See "SIMD instructions considered harmful"
50 https://sigarch.org/simd-instructions-considered-harmful
51 \item Setup and corner-cases alone are extremely complex.\\
52 Hardware is easy, but software is hell.
53 \item O($N^{6}$) ISA opcode proliferation!\\
54 opcode, elwidth, veclen, src1-src2-dest hi/lo
55 \end{itemize}
56 }
57
58 \frame{\frametitle{Quick refresher on RVV}
59
60 \begin{itemize}
61 \item Effectively a variant of SIMD / SIMT (arbitrary length)\vspace{6pt}
62 \item Extremely powerful (extensible to 256 registers)\vspace{6pt}
63 \item Supports polymorphism, several datatypes (inc. FP16)\vspace{6pt}
64 \item Requires a separate Register File (32 w/ext to 256)\vspace{6pt}
65 \item Implemented as a separate pipeline (no impact on scalar)\vspace{6pt}
66 \end{itemize}
67 However...\vspace{10pt}
68 \begin{itemize}
69 \item 98 percent opcode duplication with rest of RV (CLIP)
70 \item Extending RVV requires customisation not just of h/w:\\
71 gcc, binutils also need customisation (and maintenance)
72 \end{itemize}
73 }
74
75
76 \frame{\frametitle{The Simon Sinek lowdown (Why, How, What)}
77
78 \begin{itemize}
79 \item Why?
80 Implementors need flexibility in vectorisation to optimise for
81 area or performance depending on the scope:
82 embedded DSP, Mobile GPU's, Server CPU's and more.\\
83 Compilers also need flexibility in vectorisation to optimise for cost
84 of pipeline setup, amount of state to context switch
85 and software portability
86 \item How?
87 By marking INT/FP regs as "Vectorised" and
88 adding a level of indirection,
89 SV expresses how existing instructions should act
90 on [contiguous] blocks of registers, in parallel, WITHOUT
91 needing any new extra arithmetic opcodes.
92 \item What?
93 Simple-V is an "API" that implicitly extends
94 existing (scalar) instructions with explicit parallelisation\\
95 i.e. SV is actually about parallelism NOT vectors per se.\\
96 Has a lot in common with VLIW (without the actual VLIW).
97 \end{itemize}
98 }
99
100
101 \frame{\frametitle{What's the value of SV? Why adopt it even in non-V?}
102
103 \begin{itemize}
104 \item memcpy becomes much smaller (higher bang-per-buck)
105 \item context-switch (LOAD/STORE multiple): 1-2 instructions
106 \item Compressed instrs further reduces I-cache (etc.)
107 \item Reduced I-cache load (and less I-reads)
108 \item Amazingly, SIMD becomes tolerable (no corner-cases)
109 \item Modularity/Abstraction in both the h/w and the toolchain.
110 \item "Reach" of registers accessible by Compressed is enhanced
111 \item Future: double the standard INT/FP register file sizes.
112 \end{itemize}
113 Note:
114 \begin{itemize}
115 \item It's not just about Vectors: it's about instruction effectiveness
116 \item Anything implementor is not interested in HW-optimising,\\
117 let it fall through to exceptions (implement as a trap).
118 \end{itemize}
119 }
120
121
122 \frame{\frametitle{How does Simple-V relate to RVV? What's different?}
123
124 \begin{itemize}
125 \item RVV very heavy-duty (excellent for supercomputing)\vspace{8pt}
126 \item Simple-V abstracts parallelism (based on best of RVV)\vspace{8pt}
127 \item Graded levels: hardware, hybrid or traps (fit impl. need)\vspace{8pt}
128 \item Even Compressed become vectorised (RVV can't)\vspace{8pt}
129 \item No polymorphism in SV (too complex)\vspace{8pt}
130 \end{itemize}
131 What Simple-V is not:\vspace{4pt}
132 \begin{itemize}
133 \item A full supercomputer-level Vector Proposal
134 \item A replacement for RVV (SV is designed to be over-ridden\\
135 by - or augmented to become - RVV)
136 \end{itemize}
137 }
138
139
140 \frame{\frametitle{How is Parallelism abstracted in Simple-V?}
141
142 \begin{itemize}
143 \item Register "typing" turns any op into an implicit Vector op:\\
144 registers are reinterpreted through a level of indirection
145 \item Primarily at the Instruction issue phase (except SIMD)\\
146 Note: it's ok to pass predication through to ALU (like SIMD)
147 \item Standard and future and custom opcodes now parallel\\
148 (crucially: with NO extra instructions needing to be added)
149 \end{itemize}
150 Note: EVERYTHING is parallelised:
151 \begin{itemize}
152 \item All LOAD/STORE (inc. Compressed, Int/FP versions)
153 \item All ALU ops (Int, FP, SIMD, DSP, everything)
154 \item All branches become predication targets (C.FNE added?)
155 \item C.MV of particular interest (s/v, v/v, v/s)
156 \item FCVT, FMV, FSGNJ etc. very similar to C.MV
157 \end{itemize}
158 }
159
160
161 \frame{\frametitle{What's the deal / juice / score?}
162
163 \begin{itemize}
164 \item Standard Register File(s) overloaded with CSR "reg is vector"\\
165 (see pseudocode slides for examples)
166 \item "2nd FP\&INT register bank" possibility, reserved for future\\
167 (would allow standard regfiles to remain unmodified)
168 \item Element width concept remain same as RVV\\
169 (CSRs give new size: overrides opcode-defined meaning)
170 \item CSRs are key-value tables (overlaps allowed: v. important)
171 \end{itemize}
172 Key differences from RVV:
173 \begin{itemize}
174 \item Predication in INT reg as a BIT field (max VL=XLEN)
175 \item Minimum VL must be Num Regs - 1 (all regs single LD/ST)
176 \item SV may condense sparse Vecs: RVV cannot (SIMD-like):\\
177 SV gives choice to Zero or skip non-predicated elements\\
178 (no such choice in RVV: zeroing-only)
179 \end{itemize}
180 }
181
182
183 \begin{frame}[fragile]
184 \frametitle{ADD pseudocode (or trap, or actual hardware loop)}
185
186 \begin{semiverbatim}
187 function op\_add(rd, rs1, rs2, predr) # add not VADD!
188  int i, id=0, irs1=0, irs2=0;
189  for (i = 0; i < VL; i++)
190   if (ireg[predr] & 1<<i) # predication uses intregs
191    ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
192 if (reg\_is\_vectorised[rd] )  \{ id += 1; \}
193 if (reg\_is\_vectorised[rs1])  \{ irs1 += 1; \}
194 if (reg\_is\_vectorised[rs2])  \{ irs2 += 1; \}
195 \end{semiverbatim}
196
197 \begin{itemize}
198 \item Above is oversimplified: Reg. indirection left out (for clarity).
199 \item SIMD slightly more complex (case above is elwidth = default)
200 \item Scalar-scalar and scalar-vector and vector-vector now all in one
201 \item OoO may choose to push ADDs into instr. queue (v. busy!)
202 \end{itemize}
203 \end{frame}
204
205 % yes it really *is* ADD not VADD. that's the entire point of
206 % this proposal, that *standard* operations are overloaded to
207 % become vectorised-on-demand
208
209
210 \begin{frame}[fragile]
211 \frametitle{Predication-Branch (or trap, or actual hardware loop)}
212
213 \begin{semiverbatim}
214 s1 = reg\_is\_vectorised(src1);
215 s2 = reg\_is\_vectorised(src2);
216 if (!s2 && !s1) goto branch;
217 for (int i = 0; i < VL; ++i)
218 if (cmp(s1 ? reg[src1+i]:reg[src1],
219 s2 ? reg[src2+i]:reg[src2])
220 ireg[rs3] |= 1<<i;
221 \end{semiverbatim}
222
223 \begin{itemize}
224 \item SIMD slightly more complex (case above is elwidth = default)
225 \item If s1 and s2 both scalars, Standard branch occurs
226 \item Predication stored in integer regfile as a bitfield
227 \item Scalar-vector and vector-vector supported
228 \item Overload Branch immediate to be predication target rs3
229 \end{itemize}
230 \end{frame}
231
232 \begin{frame}[fragile]
233 \frametitle{VLD/VLD.S/VLD.X (or trap, or actual hardware loop)}
234
235 \begin{semiverbatim}
236 if (unit-strided) stride = elsize;
237 else stride = areg[as2]; // constant-strided
238 for (int i = 0; i < VL; ++i)
239 if ([!]preg[rd] & 1<<i)
240 for (int j = 0; j < seglen+1; j++)
241 if (reg\_is\_vectorised[rs2]) offs = vreg[rs2+i]
242 else offs = i*(seglen+1)*stride;
243 vreg[rd+j][i] = mem[sreg[base] + offs + j*stride]
244 \end{semiverbatim}
245
246 \begin{itemize}
247 \item Again: elwidth != default slightly more complex
248 \item rs2 vectorised taken to implicitly indicate VLD.X
249 \end{itemize}
250 \end{frame}
251
252
253 \frame{\frametitle{Register key-value CSR store (lookup table / CAM)}
254
255 \begin{itemize}
256 \item key is int regfile number or FP regfile number (1 bit)
257 \item treated as vector if referred to in op (5 bits, key)
258 \item starting register to actually be used (5 bits, value)
259 \item element bitwidth: default, dflt/2, 8, 16 (2 bits)
260 \item is vector: Y/N (1 bit)
261 \item is packed SIMD: Y/N (1 bit)
262 \item register bank: 0/reserved for future ext. (1 bit)
263 \end{itemize}
264 Notes:
265 \begin{itemize}
266 \item References different (internal) mapping table for INT or FP
267 \item Level of indirection has implications for pipeline latency
268 \item (future) bank bit, no need to extend opcodes: set bank=1,
269 just use normal 5-bit regs, indirection takes care of the rest.
270 \end{itemize}
271 }
272
273
274 \frame{\frametitle{Register element width and packed SIMD}
275
276 Packed SIMD = N:
277 \begin{itemize}
278 \item default: RV32/64/128 opcodes define elwidth = 32/64/128
279 \item default/2: RV32/64/128 opcodes, elwidth = 16/32/64 with
280 top half of register ignored (src), zero'd/s-ext (dest)
281 \item 8 or 16: elwidth = 8 (or 16), similar to default/2
282 \end{itemize}
283 Packed SIMD = Y (default is moot, packing is 1:1)
284 \begin{itemize}
285 \item default/2: 2 elements per register @ opcode-defined bitwidth
286 \item 8 or 16: standard 8 (or 16) packed SIMD
287 \end{itemize}
288 Notes:
289 \begin{itemize}
290 \item Different src/dest widths (and packs) PERMITTED
291 \item RV* already allows (and defines) how RV32 ops work in RV64\\
292 so just logically follow that lead/example.
293 \end{itemize}
294 }
295
296
297 \begin{frame}[fragile]
298 \frametitle{Register key-value CSR table decoding pseudocode}
299
300 \begin{semiverbatim}
301 struct vectorised fp\_vec[32], int\_vec[32]; // 64 in future
302
303 for (i = 0; i < 16; i++) // 16 CSRs?
304 tb = int\_vec if CSRvec[i].type == 0 else fp\_vec
305 idx = CSRvec[i].regkey // INT/FP src/dst reg in opcode
306 tb[idx].elwidth = CSRvec[i].elwidth
307 tb[idx].regidx = CSRvec[i].regidx // indirection
308 tb[idx].isvector = CSRvec[i].isvector
309 tb[idx].packed = CSRvec[i].packed // SIMD or not
310 tb[idx].bank = CSRvec[i].bank // 0 (1=rsvd)
311 \end{semiverbatim}
312
313 \begin{itemize}
314 \item All 32 int (and 32 FP) entries zero'd before setup
315 \item Might be a bit complex to set up in hardware (keep as CAM?)
316 \end{itemize}
317
318 \end{frame}
319
320
321 \frame{\frametitle{Predication key-value CSR store}
322
323 \begin{itemize}
324 \item key is int regfile number or FP regfile number (1 bit)
325 \item register to be predicated if referred to (5 bits, key)
326 \item INT reg with actual predication mask (5 bits, value)
327 \item predication is inverted Y/N (1 bit)
328 \item non-predicated elements are to be zero'd Y/N (1 bit)
329 \item register bank: 0/reserved for future ext. (1 bit)
330 \end{itemize}
331 Notes:\vspace{10pt}
332 \begin{itemize}
333 \item Table should be expanded out for high-speed implementations
334 \item Key-value overlaps permitted, but (key+type) must be unique
335 \item RVV rules about deleting higher-indexed CSRs followed
336 \end{itemize}
337 }
338
339
340 \begin{frame}[fragile]
341 \frametitle{Predication key-value CSR table decoding pseudocode}
342
343 \begin{semiverbatim}
344 struct pred fp\_pred[32], int\_pred[32]; // 64 in future
345
346 for (i = 0; i < 16; i++) // 16 CSRs?
347 tb = int\_pred if CSRpred[i].type == 0 else fp\_pred
348 idx = CSRpred[i].regkey
349 tb[idx].zero = CSRpred[i].zero // zeroing
350 tb[idx].inv = CSRpred[i].inv // inverted
351 tb[idx].predidx = CSRpred[i].predidx // actual reg
352 tb[idx].bank = CSRpred[i].bank // 0 for now
353 tb[idx].enabled = true
354 \end{semiverbatim}
355
356 \begin{itemize}
357 \item All 32 int and 32 FP entries zero'd before setting
358 \item Might be a bit complex to set up in hardware (keep as CAM?)
359 \end{itemize}
360
361 \end{frame}
362
363
364 \begin{frame}[fragile]
365 \frametitle{Get Predication value pseudocode}
366
367 \begin{semiverbatim}
368 def get\_pred\_val(bool is\_fp\_op, int reg):
369 tb = int\_pred if is\_fp\_op else fp\_pred
370 if (!tb[reg].enabled):
371 return ~0x0 // all ops enabled
372 predidx = tb[reg].predidx // redirection occurs HERE
373 predicate = intreg[predidx] // actual predicate HERE
374 if (tb[reg].inv):
375 predicate = ~predicate // invert ALL bits
376 return predicate
377 \end{semiverbatim}
378
379 \begin{itemize}
380 \item References different (internal) mapping table for INT or FP
381 \item Actual predicate bitmask ALWAYS from the INT regfile
382 \item Hard-limit on MVL of XLEN (predication only 1 intreg)
383 \end{itemize}
384
385 \end{frame}
386
387
388 \frame{\frametitle{To Zero or not to place zeros in non-predicated elements?}
389
390 \begin{itemize}
391 \item Zeroing is an implementation optimisation favouring OoO
392 \item Simple implementations may skip non-predicated operations
393 \item Simple implementations explicitly have to destroy data
394 \item Complex implementations may use reg-renames to save power\\
395 Zeroing on predication chains makes optimisation harder
396 \item Compromise: REQUIRE both (specified in predication CSRs).
397 \end{itemize}
398 Considerations:
399 \begin{itemize}
400 \item Complex not really impacted, simple impacted a LOT\\
401 with Zeroing... however it's useful (memzero)
402 \item Non-zero'd overlapping "Vectors" may issue overlapping ops\\
403 (2nd op's predicated elements slot in 1st's non-predicated ops)
404 \item Please don't use Vectors for "security" (use Sec-Ext)
405 \end{itemize}
406 }
407 % with overlapping "vectors" - bearing in mind that "vectors" are
408 % just a remap onto the standard register file, if the top bits of
409 % predication are zero, and there happens to be a second vector
410 % that uses some of the same register file that happens to be
411 % predicated out, the second vector op may be issued *at the same time*
412 % if there are available parallel ALUs to do so.
413
414
415 \frame{\frametitle{Implementation Options}
416
417 \begin{itemize}
418 \item Absolute minimum: Exceptions: if CSRs indicate "V", trap.\\
419 (Requires as absolute minimum that CSRs be in Hardware)
420 \item Hardware loop, single-instruction issue\\
421 (Do / Don't send through predication to ALU)
422 \item Hardware loop, parallel (multi-instruction) issue\\
423 (Do / Don't send through predication to ALU)
424 \item Hardware loop, full parallel ALU (not recommended)
425 \end{itemize}
426 Notes:\vspace{4pt}
427 \begin{itemize}
428 \item 4 (or more?) options above may be deployed on per-op basis
429 \item SIMD always sends predication bits to ALU (if requested)
430 \item Minimum MVL MUST be sufficient to cover regfile LD/ST
431 \item Instr. FIFO may repeatedly split off N scalar ops at a time
432 \end{itemize}
433 }
434 % Instr. FIFO may need its own slide. Basically, the vectorised op
435 % gets pushed into the FIFO, where it is then "processed". Processing
436 % will remove the first set of ops from its vector numbering (taking
437 % predication into account) and shoving them **BACK** into the FIFO,
438 % but MODIFYING the remaining "vectorised" op, subtracting the now
439 % scalar ops from it.
440
441 \frame{\frametitle{Predicated 8-parallel ADD: 1-wide ALU (no zeroing)}
442 \begin{center}
443 \includegraphics[height=2.5in]{padd9_alu1.png}\\
444 {\bf \red Predicated adds are shuffled down: 6 cycles in total}
445 \end{center}
446 }
447
448
449 \frame{\frametitle{Predicated 8-parallel ADD: 4-wide ALU (no zeroing)}
450 \begin{center}
451 \includegraphics[height=2.5in]{padd9_alu4.png}\\
452 {\bf \red Predicated adds are shuffled down: 4 in 1st cycle, 2 in 2nd}
453 \end{center}
454 }
455
456
457 \frame{\frametitle{Predicated 8-parallel ADD: 3 phase FIFO expansion}
458 \begin{center}
459 \includegraphics[height=2.5in]{padd9_fifo.png}\\
460 {\bf \red First cycle takes first four 1s; second takes the rest}
461 \end{center}
462 }
463
464
465 \begin{frame}[fragile]
466 \frametitle{ADD pseudocode with redirection (and proper predication)}
467
468 \begin{semiverbatim}
469 function op\_add(rd, rs1, rs2) # add not VADD!
470  int i, id=0, irs1=0, irs2=0;
471  rd = int\_vec[rd ].isvector ? int\_vec[rd ].regidx : rd;
472  rs1 = int\_vec[rs1].isvector ? int\_vec[rs1].regidx : rs1;
473  rs2 = int\_vec[rs2].isvector ? int\_vec[rs2].regidx : rs2;
474  predval = get\_pred\_val(FALSE, rd);
475  for (i = 0; i < VL; i++)
476 if (predval \& 1<<i) # predication uses intregs
477    ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
478 if (int\_vec[rd ].isvector)  \{ id += 1; \}
479 if (int\_vec[rs1].isvector)  \{ irs1 += 1; \}
480 if (int\_vec[rs2].isvector)  \{ irs2 += 1; \}
481 \end{semiverbatim}
482
483 \begin{itemize}
484 \item SIMD (elwidth != default) not covered above
485 \end{itemize}
486 \end{frame}
487
488
489 \frame{\frametitle{How are SIMD Instructions Vectorised?}
490
491 \begin{itemize}
492 \item SIMD ALU(s) primarily unchanged
493 \item Predication added down to each SIMD element (if requested,
494 otherwise entire block will be predicated as a whole)
495 \item Predication bits sent in groups to the ALU (if requested,
496 otherwise just one bit for the entire packed block)
497 \item End of Vector enables (additional) predication:
498 completely nullifies end-case code (ONLY in multi-bit
499 predication mode)
500 \end{itemize}
501 Considerations:
502 \begin{itemize}
503 \item Many SIMD ALUs possible (parallel execution)
504 \item Implementor free to choose (API remains the same)
505 \item Unused ALU units wasted, but s/w DRASTICALLY simpler
506 \item Very long SIMD ALUs could waste significant die area
507 \end{itemize}
508 }
509 % With multiple SIMD ALUs at for example 32-bit wide they can be used
510 % to either issue 64-bit or 128-bit or 256-bit wide SIMD operations
511 % or they can be used to cover several operations on totally different
512 % vectors / registers.
513
514 \frame{\frametitle{Predicated 9-parallel SIMD ADD (Packed=Y)}
515 \begin{center}
516 \includegraphics[height=2.5in]{padd9_simd.png}\\
517 {\bf \red 4-wide 8-bit SIMD, 4 bits of predicate passed to ALU}
518 \end{center}
519 }
520
521
522 \frame{\frametitle{Why are overlaps allowed in Regfiles?}
523
524 \begin{itemize}
525 \item Same register(s) can have multiple "interpretations"
526 \item CSRs are costly to write to (do it once)
527 \item Set "real" register (scalar) without needing to set/unset CSRs.
528 \item xBitManip plus SIMD plus xBitManip = Hi/Lo bitops
529 \item (32-bit GREV plus 4x8-bit SIMD plus 32-bit GREV:\\
530 GREV @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
531 \item RGB 565 (video): BEXTW plus 4x8-bit SIMD plus BDEPW\\
532 (BEXT/BDEP @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
533 \item Same register(s) can be offset (no need for VSLIDE)\vspace{6pt}
534 \end{itemize}
535 Note:
536 \begin{itemize}
537 \item xBitManip reduces O($N^{6}$) SIMD down to O($N^{3}$)
538 \item Hi-Performance: Macro-op fusion (more pipeline stages?)
539 \end{itemize}
540 }
541
542
543 \frame{\frametitle{C.MV extremely flexible!}
544
545 \begin{itemize}
546 \item scalar-to-vector (w/ no pred): VSPLAT
547 \item scalar-to-vector (w/ dest-pred): Sparse VSPLAT
548 \item scalar-to-vector (w/ 1-bit dest-pred): VINSERT
549 \item vector-to-scalar (w/ [1-bit?] src-pred): VEXTRACT
550 \item vector-to-vector (w/ no pred): Vector Copy
551 \item vector-to-vector (w/ src pred): Vector Gather
552 \item vector-to-vector (w/ dest pred): Vector Scatter
553 \item vector-to-vector (w/ src \& dest pred): Vector Gather/Scatter
554 \end{itemize}
555 \vspace{4pt}
556 Notes:
557 \begin{itemize}
558 \item Surprisingly powerful! Zero-predication even more so
559 \item Same arrangement for FVCT, FMV, FSGNJ etc.
560 \end{itemize}
561 }
562
563
564 \begin{frame}[fragile]
565 \frametitle{MV pseudocode with predication}
566
567 \begin{semiverbatim}
568 function op\_mv(rd, rs) # MV not VMV!
569  rd = int\_vec[rd].isvector ? int\_vec[rd].regidx : rd;
570  rs = int\_vec[rs].isvector ? int\_vec[rs].regidx : rs;
571  ps = get\_pred\_val(FALSE, rs); # predication on src
572  pd = get\_pred\_val(FALSE, rd); # ... AND on dest
573  for (int i = 0, int j = 0; i < VL && j < VL;):
574 if (int\_vec[rs].isvec) while (!(ps \& 1<<i)) i++;
575 if (int\_vec[rd].isvec) while (!(pd \& 1<<j)) j++;
576 ireg[rd+j] <= ireg[rs+i];
577 if (int\_vec[rs].isvec) i++;
578 if (int\_vec[rd].isvec) j++;
579 \end{semiverbatim}
580
581 \begin{itemize}
582 \item elwidth != default not covered above (might be a bit hairy)
583 \item Ending early with 1-bit predication not included (VINSERT)
584 \end{itemize}
585 \end{frame}
586
587
588 \begin{frame}[fragile]
589 \frametitle{VSELECT: stays or goes? Stays if MV.X exists...}
590
591 \begin{semiverbatim}
592 def op_mv_x(rd, rs): # (hypothetical) RV MX.X
593 rs = regfile[rs] # level of indirection (MV.X)
594 regfile[rd] = regfile[rs] # straight regcopy
595 \end{semiverbatim}
596
597 Vectorised version aka "VSELECT":
598
599 \begin{semiverbatim}
600 def op_mv_x(rd, rs): # SV version of MX.X
601 for i in range(VL):
602 rs1 = regfile[rs+i] # indirection
603 regfile[rd+i] = regfile[rs] # straight regcopy
604 \end{semiverbatim}
605
606 \begin{itemize}
607 \item However MV.X does not exist in RV, so neither can VSELECT
608 \item \red SV is not about adding new functionality, only parallelism
609 \end{itemize}
610
611
612 \end{frame}
613
614
615 \frame{\frametitle{Opcodes, compared to RVV}
616
617 \begin{itemize}
618 \item All integer and FP opcodes all removed (no CLIP, FNE)
619 \item VMPOP, VFIRST etc. all removed (use xBitManip)
620 \item VSLIDE removed (use regfile overlaps)
621 \item C.MV covers VEXTRACT VINSERT and VSPLAT (and more)
622 \item Vector (or scalar-vector) copy: use C.MV (MV is a pseudo-op)
623 \item VMERGE: twin predicated C.MVs (one inverted. macro-op'd)
624 \item VSETVL, VGETVL stay (the only ops that do!)
625 \end{itemize}
626 Issues:
627 \begin{itemize}
628 \item VSELECT stays? no MV.X, so no (add with custom ext?)
629 \item VSNE exists, but no FNE (use predication inversion?)
630 \item VCLIP is not in RV* (add with custom ext? or CSR?)
631 \end{itemize}
632 }
633
634
635 \begin{frame}[fragile]
636 \frametitle{Example c code: DAXPY}
637
638 \begin{semiverbatim}
639 void daxpy(size_t n, double a,
640 const double x[], double y[])
641 \{
642 for (size_t i = 0; i < n; i++) \{
643 y[i] = a*x[i] + y[i];
644 \}
645 \}
646 \end{semiverbatim}
647
648 \begin{itemize}
649 \item See "SIMD Considered Harmful" for SIMD/RVV analysis\\
650 https://sigarch.org/simd-instructions-considered-harmful/
651 \end{itemize}
652
653
654 \end{frame}
655
656
657 \begin{frame}[fragile]
658 \frametitle{RVV DAXPY assembly (RV32V)}
659
660 \begin{semiverbatim}
661 # a0 is n, a1 is ptr to x[0], a2 is ptr to y[0], fa0 is a
662 li t0, 2<<25
663 vsetdcfg t0 # enable 2 64b Fl.Pt. registers
664 loop:
665 setvl t0, a0 # vl = t0 = min(mvl, n)
666 vld v0, a1 # load vector x
667 slli t1, t0, 3 # t1 = vl * 8 (in bytes)
668 vld v1, a2 # load vector y
669 add a1, a1, t1 # increment pointer to x by vl*8
670 vfmadd v1, v0, fa0, v1 # v1 += v0 * fa0 (y = a * x + y)
671 sub a0, a0, t0 # n -= vl (t0)
672 vst v1, a2 # store Y
673 add a2, a2, t1 # increment pointer to y by vl*8
674 bnez a0, loop # repeat if n != 0
675 \end{semiverbatim}
676 \end{frame}
677
678
679 \begin{frame}[fragile]
680 \frametitle{SV DAXPY assembly (RV64D)}
681
682 \begin{semiverbatim}
683 # a0 is n, a1 is ptr to x[0], a2 is ptr to y[0], fa0 is a
684 CSRvect1 = \{type: F, key: a3, val: a3, elwidth: dflt\}
685 CSRvect2 = \{type: F, key: a7, val: a7, elwidth: dflt\}
686 loop:
687 setvl t0, a0, 4 # vl = t0 = min(4, n)
688 ld a3, a1 # load 4 registers a3-6 from x
689 slli t1, t0, 3 # t1 = vl * 8 (in bytes)
690 ld a7, a2 # load 4 registers a7-10 from y
691 add a1, a1, t1 # increment pointer to x by vl*8
692 fmadd a7, a3, fa0, a7 # v1 += v0 * fa0 (y = a * x + y)
693 sub a0, a0, t0 # n -= vl (t0)
694 st a7, a2 # store 4 registers a7-10 to y
695 add a2, a2, t1 # increment pointer to y by vl*8
696 bnez a0, loop # repeat if n != 0
697 \end{semiverbatim}
698 \end{frame}
699
700
701 \frame{\frametitle{Under consideration}
702
703 \begin{itemize}
704 \item Should future extra bank be included now?
705 \item How many Register and Predication CSRs should there be?\\
706 (and how many in RV32E)
707 \item How many in M-Mode (for doing context-switch)?
708 \item Should use of registers be allowed to "wrap" (x30 x31 x1 x2)?
709 \item Can CLIP be done as a CSR (mode, like elwidth)
710 \item SIMD saturation (etc.) also set as a mode?
711 \item Include src1/src2 predication on Comparison Ops?\\
712 (same arrangement as C.MV, with same flexibility/power)
713 \item 8/16-bit ops is it worthwhile adding a "start offset"? \\
714 (a bit like misaligned addressing... for registers)\\
715 or just use predication to skip start?
716 \end{itemize}
717 }
718
719
720 \frame{\frametitle{What's the downside(s) of SV?}
721 \begin{itemize}
722 \item EVERY register operation is inherently parallelised\\
723 (scalar ops are just vectors of length 1)\vspace{4pt}
724 \item Tightly coupled with the core (instruction issue)\\
725 could be disabled through MISA switch\vspace{4pt}
726 \item An extra pipeline phase almost certainly essential\\
727 for fast low-latency implementations\vspace{4pt}
728 \item With zeroing off, skipping non-predicated elements is hard:\\
729 it is however an optimisation (and need not be done).\vspace{4pt}
730 \item Setting up the Register/Predication tables (interpreting the\\
731 CSR key-value stores) might be a bit complex to optimise
732 (any change to a CSR key-value entry needs to redo the table)
733 \end{itemize}
734 }
735
736
737 \frame{\frametitle{Summary}
738
739 \begin{itemize}
740 \item Actually about parallelism, not Vectors (or SIMD) per se\\
741 and NOT about adding new ALU/logic/functionality.
742 \item Only needs 2 actual instructions (plus the CSRs).\\
743 RVV - and "standard" SIMD - require ISA duplication
744 \item Designed for flexibility (graded levels of complexity)
745 \item Huge range of implementor freedom
746 \item Fits RISC-V ethos: achieve more with less
747 \item Reduces SIMD ISA proliferation by 3-4 orders of magnitude \\
748 (without SIMD downsides or sacrificing speed trade-off)
749 \item Covers 98\% of RVV, allows RVV to fit "on top"
750 \item Byproduct of SV is a reduction in code size, power usage
751 etc. (increase efficiency, just like Compressed)
752 \end{itemize}
753 }
754
755
756 \frame{
757 \begin{center}
758 {\Huge The end\vspace{20pt}\\
759 Thank you\vspace{20pt}\\
760 Questions?\vspace{20pt}
761 }
762 \end{center}
763
764 \begin{itemize}
765 \item Discussion: ISA-DEV mailing list
766 \item http://libre-riscv.org/simple\_v\_extension/
767 \end{itemize}
768 }
769
770
771 \end{document}