5

I'm really confused on the difference between bubbles, stalls, and repeated decoding/fetching. My text is the Patterson text, 3rd edition.
Example 1:

add $3, $4, $6
sub $5, $3, $2
lw $7, 100($5)
add $8, $7, $2

Solution: Click here (Using an image because it is very hard to type out what is there)
In this example/solution, FIVE bubbles are inserted into a new row in between the 3rd and 4th instructions.

Example 2:

lw $4, 100($2)
sub $6, $4, $3
add $2, $3, $5

Solution: Click here
In this example, a bubble wraps the 2nd and 3rd instruction in clock cycle 4. In clock cycle 4, I2's decode is repeated and I3's fetch is repeated.


What is the difference between examples 1 and 2? Why is a row of bubbles inserted in example 1 whereas in example 2, a bubble is inserted and decode/fetch repeats? Are they functionally the same? If they are functionally the same, is this a valid solution for example 1?

I1: IF ID EX MEM WB
I2:    IF ID EX  MEM WB
I3:       IF ID  EX  MEM WB
I4:          IF  NOP ID  EX MEM WB 

Would this also be a valid solution for example 1?

I1: IF ID EX MEM WB
I2:    IF ID EX  MEM WB
I3:       IF ID  EX  MEM WB
I4:          NOP IF  ID  EX MEM WB 

Would this be a valid solution for example 2?

I1: IF ID EX  MEM WB
I2:    IF NOP ID  EX MEM WB
I3:       NOP IF  ID EX  MEM WB

Would this also be a valid solution for example 2?

I1: IF ID EX  MEM WB
I2:    IF ID  ID  EX MEM WB
I3:       IF  IF  ID EX  MEM WB
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
John D
  • 51
  • 4
  • Do yourself [and everybody] a favor. It's okay to use images, but don't _link_ to them, but _embed_ them (e.g. edit the question and click on the image icon, then enter your original imgur url). Done correctly the image will now embed and will be stored at the same url. The reason I say "do _yourself_ a favor" is that most people won't bother with a question if it has linked images. To see an example, look at your prior question, which I edited to embed the images – Craig Estey Mar 12 '17 at 04:18
  • @CraigEstey Not allowed to link to the image as I don't have enough reputation. – John D Mar 12 '17 at 04:36
  • As far as Wikipedia is concerned, a pipeline stall and pipeline bubble are the same thing: https://en.wikipedia.org/w/index.php?title=Pipeline_bubble&redirect=no. – Erik Eidt Feb 05 '23 at 00:27

2 Answers2

3

A bubble in the pipeline (sometimes represented by a NOP) is the result of stalling for 1 cycle.

A bubble is something you see and talk about when looking at a pipeline diagram of how instructions go through the pipeline, and what stage they're in at any given cycle. A bubble propagates through the pipeline, so it appears in each stage once. (For a structural hazard like instruction fetch competing with data load/store, the bubble will start in IF, like your first example.)

A stall is something that a single stage decides to do, creating one or more bubbles depending on how long it stalls for.


A row of bubbles vs. a bubble within the row for an instruction

Notice that they've added a vertical row for the one bubble going through all 5 stages of the pipeline. As if you'd written a NOP in your program to fill the load delay slot (necessary on MIPS I R2000 / R3000 if you can't schedule other instructions to fill it; on later MIPS the ISA guarantees that hardware will stall for you). Except a true nop in the machine code still gets fetched and decoded. MIPS doesn't have a special opcode for nop, you write one as add $zero, $zero, $zero or equivalent with no inputs to stall for and an output of $zero which ignores writes, always reads as zero.

Vertical rows are for instructions, not time. Stalls mean that later instructions (or stages of them) start farther to the right, not in the cycle after the current one reaches that stage.

The diagram could indicate the same timing by skipping a clock cycle (column) for the IF stage of the instruction after the load. You could maybe draw one bubble to the left of that IF, in the spot where IF would normally fetch it in the cycle after fetching the lw.


The diagram is not how a real CPU would execute the example 1 code. You didn't include the captions in your question, which would probably have explained why they drew it that way. Perhaps showing that leaving a gap before even starting the instruction would solve the problem.

A CPU running that code won't know whether or not the instruction after an lw depends on the result until it has fetched and decoded it. That's where it checks for hazards. The cycle after add $8, $7, $2 reaches ID is when IF would either be idle or re-fetch the instruction after the add.

Your example 2 is the more normal way to draw things, showing a load delay (on MIPS II or later), where the load result isn't available for forwarding until after stalling for a cycle, so ID does that and sets up the forwarding. The instruction not moving forward in the pipeline leaves a bubble that you can see in the next few instructions: note that EX didn't appear in cycle 4. And that MEM didn't appear in cycle 5. etc. That's the bubble moving through the pipeline over time.

The same instruction staying around in reg reg (decode) is the back pressure created by the stall to open up that bubble.


A row of 5 bubbles due to a structural hazard on instruction fetch

In my copy of Patterson & Hennesy (2nd edition), Figure 3.7 has a row of 5 bubbles, but for a different reason than your example 1. It's talking about a machine without split L1i / L1d caches, or with no cache and single-ported memory, hence IM/DM (instruction memory / data memory stages). You omitted the caption, which is

Figure 3.7 The structural hazard causes pipeline bubbles to be inserted. The effect is that no instruction will finish during clock cycle 8, when instruction 3 would normally have finished. (Instruction 1 is assumed to not be a load or store; otherwise, instruction 3 cannot start execution).

The "code" and pipeline diagram is figure 3.9: A pipeline stalled for a structural hazard - a load with one memory port.

 load                IF  ID  EX  MEM  WB
 instruction 1           IF  ID  EX   MEM WB
 instruction 2               IF  ID   EX  MEM WB
 instruction 3                (stall) IF  ID  EX  MEM WB  ; (would be in IF at the same time the load is in MEM, structural hazard)
 instruction 4                            IF  ID  EX  MEM WB  

Figure 3.6 shows the conflict if you don't have a stall/bubble. In the 2nd edition of the book, they actually label both the first and fourth pipeline stages as MEM, instead of IF/MEM or IM/DM.

I don't know if my copy of the textbook has a diagram like yours at some later point when they're talking about data hazards. I didn't flip through it further. Perhaps they're showing how an idle cycle there would make the dependency work, and will go on to show what really happens, that the CPU has to fetch and decode to discover the hazard.


Another answer claims that a stall would let the control signals go down the pipeline unchanged instead of inserting a NOP, but that doesn't sound right or seem practical.

Letting add $8, $7, $2 go through the pipeline with a wrong value for the $7 input doesn't seem not directly harmful; a scalar in-order pipeline doesn't have WAW or WAR hazards so letting it reach the WB stage and write a wrong value into the register file isn't going to hurt correctness of other instructions; the right value will get written in the next cycle, when the instruction goes through the pipeline again with the right value this time... Unless an interrupt is taken in that cycle while the register file holds the wrong value!! Then there's an architecturally-visible wrong value.

It would also be a problem for memory operations to let them run in the MEM stage with potentially a bad pointer as part of the addressing mode. You could get a spurious TLB miss or page fault, or a store to the wrong place.

So very likely a stage that detects a stall would mux some of the control bits to send a NOP down the pipe, or there'd be a dedicated control line for NOP/bubble to deactivate stages.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    "A stall is something that a single stage decides to do, creating one or more bubbles depending on how long it stalls for." This made it click for me, thank you so much!! – Jordan Feb 04 '23 at 01:07
  • 1
    @Jordan: I'm not sure if that's widely agreed upon as specific technical meanings. It wouldn't be totally wrong in most cases to say "stall" to talk about the empty slot going through the pipeline. (But maybe not vice versa, saying a stage had to bubble because of a resource conflict sounds unusual to me.) "Bubble" and "stall" are terms that still get used even in modern superscalar out-of-order exec CPUs, with bubble normally meaning lost work or empty slots (especially in the in-order front-end), and stalls being when no work is happening other than e.g. waiting for cache or branch misses. – Peter Cordes Feb 04 '23 at 01:29
0

I know the question is old, but I hope this helps. Stalling and bubbling is used in different context. Stalling represents keeping the register with the same inputs and continuing onto the next stages with same inputs, meaning no output or no regsisters inputs are different, while bubble represent a NOP instruction, that will make the register inputs be 0(If i am not wrong). Now the difference between bubble and stalling you can understand by the following example. In the case of a jump mispredicted branch you have following instructions that you dont know yet if they will be taken or not. For cost purposes of delay and bandwidth the stalling will keep the decode stage in stalling, while if a bubble would be entered you will be back of two stages the fetch and the decode. In the case the branch was good selected and was stalled, then the resume will be already in the decode stage, while if was bubbled the result would have to start again from the fetch instruction. I think that the difference is also of costs, in adding inputs to registers.

DharmanBot
  • 1,066
  • 2
  • 6
  • 10
Mr N
  • 53
  • 9
  • 1
    Do you or anyone know of any good resources that explain this more exhaustively? Every resource seems to treat them as synonymous and I'm having trouble understanding and visualizing when to use one over the other. – Jordan Feb 03 '23 at 18:49
  • 1
    @Jordan: This answer sounds odd to me; I would have said bubbles in the pipeline are the result of stalling. As far as what control signals you actually send along to later stages of a simple in-order pipeline, it might be safe to let an arbitrary instruction just go; in-order scalar pipelines won't have WAW or WAR hazards, so it's safe to let a register write happen early with garbage values (since the register inputs we need aren't ready yet, that's why we're stalling). But not a memory load or store: with the wrong address, a spurious TLB miss or page fault could happen. – Peter Cordes Feb 03 '23 at 19:21
  • 1
    @Jordan: So probably you'd either mux some of the control bits to send a NOP down the pipe (or at least a non-memory operation), or have a separate signal line to indicate stall. Hmm, even letting registers get written with wrong values isn't safe because an interrupt could happen on any cycle. – Peter Cordes Feb 03 '23 at 19:24
  • Does this mean there's two "types" of bubbles? One resulting from a stall signal and one resulting from a NOP? So a stall always causes a bubble but a bubble is not always caused by a stall? – Jordan Feb 03 '23 at 20:30
  • 1
    @Jordan: A `nop` in the machine code is a real instruction that you can potentially single-step or set a breakpoint on. A bubble resulting from a stall isn't. A `nop` in the machine code still increments the program counter, unlike a stall. Some people talk about a bubble as a "nop" invented by the pipeline; if that's the kind of NOP you mean, then no, there aren't different kinds of stalls, just different reasons for needing to stall. This answer is pretty much just wrong. – Peter Cordes Feb 03 '23 at 20:32
  • @Jordan: I posted my own answer. – Peter Cordes Feb 03 '23 at 20:45