Okay. Let's, let's begin today. So, we are going to start where we left off last time, which was talking about in order super scalars, so as you may recall just a brief review. We were talking about these sort of, little bit more complex pipelines. We were able to execute multiple instructions at the same time. Sometimes instructions had to sort of be steered, if you will, between the A and the B pipe, coming from the two different instruction registers. We have to double our decode. We need to check to make sure that there's no dependencies between, the instructions we're trying to issue at the same time, and our decode logic will do that. So there's going to be some sort of cross communication inside of there. And in our previous example we were looking at an asymmetric pipeline. So what I mean by that is, you know, loads and stores went down this pipe. And branches, and you've obviously done this pipe, and also you've obviously done this pipe. So where we left off last time. Was talking about alignment and how do we deal with fetching multiple instructions from an instruction memory or instruction cache but at the same time how do we not have to make this structure have many, many ports for instance or do we, does it have to have many, many ports. So, we looked at a, a basic piece of code here, which has whole lot of interesting alignment issues. So, at the beginning here we were basically fetching the instructions which were nicely aligned into the caches, blocks, and then we, yeah, this one was okay. We jumped to the beginning of the block. That was fine. Here, we jump to the middle of a block. And depending on how our cache was implemented, we might need to do, sort of, two fetches. Let's say you could only, read out your cache half a block at a time. Then you might have to do a fetch to get this and a fetch to get that. And then, here, you know, things were sort of cross cache lines, across, complete cache blocks. Which is, quite a bit harder. So let's, let's take a look at this. So if we have some alignment constraints, So let's say the alignment constraint we have here is that you can only fetch either from the first half, or the second half of a block at a time. And if you're trying to execute something which straddles a cache line, you're gonna have to fetch even more data. So as you can see, if you recall from this figure, this, this, and that instruction or piece of data in the RAM, when we go forward, we're basically going to be fetching extra data with that alignment constraint than we would have been fetching otherwise. This gets even harder, you know, it's, it's okay to sort of over-fetch. It's another thing if you actually have to sort of straddle a cache line here. And, cause the question comes up, "Do you, can you fetch those two at the same time from the cache, or not?" and we'll look through an example here. We're gonna look with this alignment constraint and see that, no, if you can't actually fetch that you're gonna be introducing what's affection, effectively dead cycles going down the pipe, which hurts your clocks per instruction. So here is the same instruction sequence that we had here, and these stalls, or not stalls, I mean, dead instructions that go on the pipe here are killed. The instructions that go down the pipe are actually just these three X's. So we, effectively, over-fetched, and then you know, when we go to over-fetch, let's say, here, we fetched 208, but we had to fetch, 20C, and that's instruction that shouldn't go in the pipe and not actually do anything. So you can see that you can actually, whip, when you have alignment constraints you basically can just introduce extra stall, or extra dead instructions going down the pipe and you're not actually using that. And that's not necessarily great.