1 # Out-of-out-of-Order: Unpredictable Predication Predicament
3 So, early in the development of the Not-So-Simple-V specification it was
4 identified that it meshed well with a multi-issue microarchitecture.
5 Recall that the basic principle is that registers are "tagged" through
6 a CSR table as "vectorised", and, if the Vector Length is greater than 1,
7 *multiple* (sequential) instructions are issued to the pipeline (where
8 one would normally be sent), *without* increasing the Program Counter,
9 the difference between these otherwise identical instructions being that
10 the source (and/or) destination registers are incremented continuously by
13 The nice thing about a multi-issue microarchitecture is that it is very
14 simple to drop these element-based otherwise-identical instructions directly
15 into the instruction FIFO. What is even nicer is: when predication is
16 introduced, all that needs to be done is that when the relevant element
17 predicate bit is clear, the associated element-based instruction is
18 **not** placed into the multi-issue instruction FIFO.
20 Simple, right? Couldn't be easier.
22 The problem is: the predicate and the source and the destination registers
23 can all come from the *same register file*. So, one instruction may modify
24 an integer register that on the *next instruction* is used as a predication
25 target. That creates a write-hazard that has to be dealt with, as the
26 predicated (Vectorised) instruction simply cannot be allowed to proceed
27 until the instruction that is calculating its predicate has actually
28 completed. That means that in this particular out-of-order architecture,
29 the instruction issue phase **itself has to become a Function Unit**.
31 Let me repeat that again: the instruction issue phase that deals with
32 predication **itself** has to have its own scoreboard Dependency Matrix entry.
34 This brings some quite fascinating (read: scary) challenges and opportunities.
35 If handled incorrectly, it means that the entire idea of using a multi-issue
36 instruction FIFO is toast, as there will be guaranteed stalling whenever
37 a predicated vectorised instruction is encountered.
39 Normally, a multi-issue engine has a guaranteed regular number of instructions
40 to process and place in the queue. Even branches do not stop the flow
41 of placement into the FIFO, as branch prediction (speculative execution) can
42 guess with high accuracy where the branch will go. Predicated vectorised
43 instruction issue is completely different: we have *no idea* - in advance -
44 if the issued element-based instruction is actually going to be executed
45 or not. We do not have the predicate source register (yet) because it
46 hasn't been calculated, because the prior instruction (which is being
47 executed out-of-order, and is **itself** dependent on prior instruction
48 completion) hasn't even been started yet.
50 Perhaps - thinking out loud - it would be okay to have a place-holder,
51 waiting for the predicate bits to arrive. Perhaps it is as simple as
52 adding an extra source register (predicate source) to every single Function
53 Unit. So instead of each Function Unit having src1 and src2, it has
54 src1, src2, predicate "bit". Given that it is just a single bit that each
55 Function Unit would be waiting for, it does seem somewhat gratuitous,
56 and a huge complication of an otherwise extremely simple scoreboard
57 (at present, there are no CAMs and no multi-wire I/Os in any of the
58 cells of either the FU-to-FU Matrix or the FU-to-Register Dependency Matrix).
59 Therefore, having **separate** Function Unit(s) which wait for the
60 predication register to be available, that are themselves plumbed in to
61 the actual Scoreboard system, decoding and issuing further instructions only
62 once the predicate register is ready, seems to be a reasonable avenue to
65 However, the last thing that we need is to stall execution completely,
66 so a lot more thought is going to be needed. The nice thing about having
67 a predicated vectorisation "Issue" Function Unit is: some of the more
68 complex decoding (particularly REMAP) can hypothetically be pipelined.
69 However that is **guaranteed** to result in stalled execution, as the
70 out-of-order system is going to critically depend on knowing what the
71 dependencies **are**! Perhaps it may be possible to put in temporary
72 "blank" entries that are filled in later? Issue place-holder instructions
73 into the Dependency Matrix, where we know that the registers on which
74 the instruction will depend is known at a later date?
76 Why that needs to be considered is: remember that the whole basis of
77 Simple-V is: you issue multiple *sequential* instructions. Unfortunately,
78 REMAP jumbles up the word "sequential" using a 1D/2D/3D/offset algorithm,
79 such that the actual register (or part-register in the case of 8/16/32-bit
80 element widths) needs a calculation to be performed in order to determine
81 which register is to be used. And, secondly, predication can entirely
82 skip some of those element-based instructions!
84 Talk about complex! Simple-V is supposed to be simple! No wonder
85 chip designers go for SIMD and let the software sort out the mess...
87 # Placeholder instructions: predication shadow
89 Recall from earlier updates that Mitch Alsup describes, in two unpublished
90 book chapters, some augmentations and modernisations to the 6600 Scoreboard
91 system, providing speculative branch execution as well as precise exceptions.
92 Both are identically based on the idea of adding a "schroedinger" wire that may
93 be used to kill off future instructions, along-side an additional
94 **non-register-based** Write Hazard dependency that prevents register
95 writes from committing, **without** preventing the instruction from actually
96 calculating the result that is to be written (once or if permitted).
98 Mentioned above is the idea of issuing "place-holder" instructions. These
99 are basically instructions which are waiting for their relevant predicate
100 bit to become *available*. They could hypothetically actually still be
101 executed (or at least begin execution). They would however **not** be
102 permitted to commit the results to the register file, and they would be
103 "shadowed" by the above-proposed "Predication Calculating Function Unit".
105 This ineptly-named Function Unit would have the relevant predication register
106 as its src, just like any other Function Unit with dependent source registers.
107 It would similarly have a "schroedinger" wire, and it would similarly
108 cast a write-block shadow over the Vectorised instructions that were waiting
109 for predication bits.
111 Once the predicate register is available, the Predicate-computing FU would
112 begin "farming out" individual bits of the predicate, calling "Go\_Die"
113 schroedinger signals on those Vectorised instructions where their associated
114 predicate bit is zero (or, for when zeroing is enabled, turn them into
115 "zero result" instructions), and for those instructions where the predicate
116 bit is set, cancel the write-block shadow.
118 Whether this is a wise utilisation of resources is another matter. If
119 predication is routinely 50% or less, a significant portion of the Vectorised
120 Function Units could hypothetically be calculating results that are *known*
121 to be discarded almost immediately. Also, the whole point of the exercise
122 of using a multi-issue execution engine was to save resources, not allocating
123 instructions *at all* where the predication bit for that Vectorised operation
126 However, it is better than the alternatives, and it's possible to
127 keep to a multi-issue micro-architecture as well, which is important in
128 order to achieve the target performance. Ultimately, simulations can tell us
129 whether the GPU and VPU workloads will have significant predication better
130 than guessing will: we'll just have to see how it goes.