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