And the first goes into the, the fetch stage.
But the problem here is we actually need to stall the fetch stage, or we need to,
be, because we don't know that the second instruction is the second instruction yet.
We don't, for instance, we don't know that this first instruction is not a branch or
a jump. So we don't know the address of the next
instruction. That's kind of odd.
Now why do we not know this? So, going back to, to this example here.
One thing that's common through all these different cases, is they all need to
decode the op code. Well, where do we do the decoding of the
op code? We don't do that until the decode stage of
the pipe. So we don't do that until here.
And we're not able to use that information until the end of the cycle, which would be
sort of here. And we would need that information to
determine what's going on here. So if you had a branch, for instance here
where it's not able to get around and change the program counter and change what
is being indexed into the instruction memory on this cycle.
So, what we're going to have to do, is we're going to have to insert a decode
bubble here for this structural hazard. Now, if you sort of play this forward for
more instructions, what you're going realize is this is not very efficient.
Every instruction that goes down the pipe is going to hit a control hazard, and
every instruction that goes down the pipe, you're going to basically going to hit
this decode, decoding hazard, and every instruction now takes two cycles.
So your clock per instruction for this is not gonna be very good.
Let's, let's analyze that now so we can, we can draw this in the other pipeline
diagram axis and see that what's happening here is we're, let's take the execute
stage. We're executing instruction I1, there were
no oping. Instruction I2, no op.
I3 no op. And, and you compute this all out, you end
up with a CPI of two. So your machine is running at strictly
half the performance that you want it to run at.
Well that's, that's not very good. So let's start to talk about some
techniques to, mitigate the effect of control hazards.
And, we're gonna actually have a whole lecture later in the course about branch
prediction which is one of the main techniques, in order to, mitigate control
hazards. But let's, let's move forward here and,
and take a look at one of these techniques, and this technique is
speculation. So what's the solution to this?
So the most basic solution is we actually speculate that the next address is going
to not be a branch, or the current instruction is not going to be a branch,
the next address is going to be the PC plus four.
So what does this look like in a pipe? Well, there's this nice adder here.
We're going to take the PC, and if nothing else is happening sort of later on in the
pipe we're just going to be selecting PC+4 on this control path here.
So we're just going to be sort of walking down here, we are gonna be, doing,
executing 96, 100, 104 and we are not actually gonna even look at the
instructions, until, lets say, something more interesting happens.
So, we can just speculate, that the next, next address is PC + four.
So, that's, that's great, but that adds some wriggles.
What happens when we have, like a, a jump here?
Hm, so this jump, if we speculated PC plus four, we went and fetched instruction
three here which is at address 104, but the jumps says we're supposed to go to
304, so this instruction is not even supposed to execute.
So we need some mechanism to kill instructions in the pipeline, kill live
instructions in the pipe. So how do we, how do we go about doing
this? So let's, let's look at a brief example
here. So we need some way to kill an
instruction, and what we're going to do is we're going to add a multiplexer here,
which will, multiplex in a no-op. And if we have a jump that gets to the
decode stage of the pipe, we're going to wire back in and say, oh, that instruction
that we just executed, or the instruction we just fetched, this one here, it, it's
not actually supposed to go down the pipe. We should, we should kill it.
So we're going to swing this mux, and right at the end of the cycle, we're gonna
say, no, that's actually a no op. We're gonna insert into the pipe, and
we're gonna redirect this multiplexer here to the actual jump location.
And this is what I was talking about before about the extra adder here.
Here's our extra adder which is computing our destination.
And sometimes people try to sort of put these two things together but we're gonna
take part of the instruction and we're gonna take current PC and add to that and
that's gonna compute our new destination of the jump.