Okay. So let's. We're, we're almost to the end here le, of, of control, hazards. Let's talk about why an instruction may not be dispatched every cycle. Well. Let's, let's think about forwarding and full bypassing. This is sometimes really expensive to add. If you are gonna bypass every location in your pipe, that may be expensive. So, we may still want to stop in certain cases. A good example of this is, if you go look at a modern day, something like your core I7 machine, they actually don't bypass between all the different functional units, from all the different locations, because they have, can execute about six instructions per cycle. And there, they have many stages in the depth of their pipe, so they'd have to basically be bypassing at a hundred different places for every new source off branch. So, what you typically will do, is you'll figure out, what are the common bypasses that are needed, are the common forwarding paths that are needed and you'll have those. And then some of the infrequently used ones, you just won't build. This will help with your cycle time, but hurt with your CPI. Loads, Can have a, or, typically have a 2-cycle latency. So we talked about this when we were talking about, load to use, and the instruction after the load. Cannot necessarily use the result, definitely cannot use the result because the in our five stage mix pipeline the result is not computed into the memory stage, so if you are in the SQ stage you would not have been able to get that even if you had bypassing out of the ends of the load end of, end of the load pipe or to the end of the memory stage. And one interesting thing is that the MIPS I Architecture. Actually defines low delay slots, very similar to what we have in What, what, what is what we had discussed with branch delay slots. So MIPS I had load delay slots, which were software visible, Slots that you had to fill and could solve, basically, this pipelining hazard. And the compiler would have to schedule some non-dependent instruction. So it was instruction which was not dependent on the load into that, that, that spot. This was ultimately removed out of the ISA and stalling was put back in cause as you went to different pipeline lanes and different micro-architectures this, this started to, to be onerous. And this is really one of the big problems with both load delay slots and branch delay slots is it's not very micro-architecture independent. So as you change to different micro architectures if you have let's say a pipeline length of five and it went to four, all of sudden maybe you didn't need that branch to lay slot or something, something like that. And. I wanted to sort of point out here is, this idea here, really is encapcilated in the name MIPS. It stands for microprocessor without interlocked pipeline stages. So, they really did not want to have interlocking here on something like the load to use of that, and later in MIPS two that, that was removed in pipeline interlocks were reintroduced. So, they, you know, we can all find mistakes that we have done and, and have changed it, but in the original MIPS 1ISA they had load delay slots. Another good reason why CPI might be greater than one is we have conditional branches which can cause bubbles. So this was all the control hazards we've been talking about up to this point, and you may have to kill the instructions if you don't have some sort of delay slots. Now, I wanted to point out here when we talk about cpi, and this is this note at the bottom of the slide, is that you really wanna think about Cpi from the perspective of a useable CPI, instead of How many instructions are executing. So if you are adding no-ops to your program, and the no-ops are not doing anything useful, that does not go into, that should not go into your useful CPI, calculation. Your machine might count that as valid instructions going down the pipe because you, it was software-invisible instructions, but that's not a good solution. What you should be computing in CPI, you should always be thinking about useful CPI, or CPI that's actually towards the end-goal of the program. Couple other control hazards That we need to talk about in this course are other things that can change your control flow of your program. And, those largely can fall into two different cases here. Exceptions and interrupts. And they're both related. And let's talk about what an exception is. So an exception is something where you have an instruction And the instruction does some operation, which is invalid or against what the intended use of machining. So, a good example of this, a couple good examples, is divide by zero. You take some value and divide it by zero. Well, on most computer architectures this is ill-defined or undefined. So you'll actually get an exception, which is a divide by zero error. And you can go try this out. You can go log in to your computers, and go run a little C program. Take some number, divide it by zero, you're going to get a div by zero error if you're running on Linux. And get something similar if you're running on Windows. And, Another good example of exceptions is, things like a, memory fault. Your trying to access your not allowed to go access. Some underflow and overflow exceptions in certain architectures. If like number precision goes out of, out of wack. If you have a, a, floating point number becomes too large or too small, and the floating point arithmetic can't handle the precision you'll sometimes get overflow and underflow exceptions. And then it interrupts our external things happening. And what's, So, something like a timer tick going off, or an IO device trying to wake up your processor, or do something to your processor. And why these are important, why these are control hazards, is these are unexpected things, sort of, coming into the, the instruction stream, and it's going to change. The subsequent instructions that are executing so, but it really is a control hazard flow. It's changing the program control flow. And we're going to be talking a lot more about exceptions and interrupts, later in this course, but I just wanted to get this idea across in this review so far that exceptions and interrupts are different types of control flow hazards.