 In the last couple of lectures, we have been discussing about different types of hazards and in the last lecture, we have focused on control hazard and we have seen how various compiler based approaches can reduce the penalty arising out of control hazard. And today we shall focus on dynamic approaches. So, here is a quick recap on the importance of stall reduction and this is very crucial in modern processors, where multiple instructions are issued and to keep the different functional units busy inside a processor, there is a need to have a steady stream of instructions and stalls due to control hazards dominate. It has been found that stalls due to control hazard is dominating. The reason for that is as more and more number of instructions are issued in a single cycle as it is done in a superscalar architecture, the gap between two branches reduces in terms of instruction cycle. For example, if there is a branch after four instructions and if three instructions are issued in a particular cycle, then in the next cycle itself that branch will appear. That means, the branch frequency increases and so far we have looked at static schemes for reducing branch penalties and same scheme applies to every branch instruction. That means, the techniques that we have discussed in the last lecture, we have discussed some schemes like not taken, branch taken or not taken and that particular assumption or prediction is applied to every branch instruction. Now, whenever you execute a program, same branch instruction may be taken at a particular instant and in another instant it may be untaken. So, dynamically the situation changes which cannot be captured by the compiler based approach, where we assume that always branch is either taken or not taken. So, can choose most appropriate schemes separately for each instruction. So, what we can do? We can go for some dynamic technique which can learn appropriate scheme based on observed behavior. At run time when the program is in execution, that time it can identify, I mean it can learn from the appropriate scheme based on the observed behavior which we shall discuss today. And dynamic branch prediction schemes, there are several branch prediction schemes that we shall discuss for both direction t and t and target prediction. That means, whether branch will be taken or not taken and also the target at this prediction will be all carried out simultaneously or together. And this feature has become the most important element of all modern processors. And we have seen that, this is what we discussed in the last lecture, three stall architecture and how it can be improved to have one stall architecture. Then we have discussed various static streams predict branch taken, predict branch not taken and how to use this delay slot in a very effective way such that the penalty due to branch is reduced, these things we have discussed. So, today we shall discuss about dynamic schemes where we shall be using branch prediction buffers and also we shall be using branch target buffers. That means branch prediction buffers will hold information about whether a branch will be predicted taken or untaken. On the other hand, the branch target buffers will hold information about the target address. Normally, target address is taken after computation in the instruction, but whenever you are predicting, then branch target buffer can also be stored in cache memory and from where it can be read and used for generating the target address and instruction fetch can take place from that target address. And also return address tax can be used where there are many return address instructions. Those return instruction addresses can be stored in a stack and with the help of all these dynamic schemes, the performance of a processor can be significantly improved over control hazards. And as I have already mentioned in the last lecture, basic idea of branch prediction is it is assumption that branch assumption is correct. If yes, then we have gained a performance improvement, otherwise we discard instruction and in such a case, few cycles are wasted. And there are two basic approaches, first one is direction based approach which are used by compilers and another is profile based approach which we shall be discussing today. So, we have already seen the direction based approach. These are very simple to implement and say a branch is taken or not taken. However, often branch behavior is variable. So, it is dynamic as I mentioned and misprediction rates can vary from 59 percent to 9 percent and on the average it is 34 percent. So, this cannot capture, this static based approach is used by compilers based on compilers cannot capture such behavior at compile time with simple direction based prediction. So, it is necessary to have history based approach. That means, as the program is executed, based on the history or profile the prediction is done. So, you have to maintain some information in hardware which will do this. So, this history based branch prediction an important example is state based branch prediction. So, here you will require two parts, number one is predictor. Predictor will try to guess whether an instruction will branch or not and also where it will branch. So, this is the job of the predictor and it will set a bit to one or zero depending on whether branch is taken or not taken. So, when a branch is taken, it will store some information, a particular flag bit which will be one if it is taken and if it is not taken it will be zero. So, pipeline checks bit values and predicts that means whatever is stored based on a previous history that will be used to predict whether the branch will be taken or not taken. The prediction is a hint that is assumed to be correct. So, you must remember one thing, this prediction that we are doing is essentially a hint and prediction may be incorrect. So, if it is correct then we gain, if it is not correct then the gain is not there. So, that you should keep in your mind and whenever you do the prediction fetching vegans in the predicted direction whether it is taken or not taken. And obviously, this type of state based branch predictions should have a recovery mechanism. By recovery mechanism, I mean whenever the prediction turns out to be incorrect or wrong, the prediction bit is inverted to fix the mistake. That means say earlier if a branch was taken, now it is untaken or not taken. So, the bit has to be inverted and that is done in the recovery mechanism. So, let us first focus on the simplest, histigrist branch prediction that is using one bit predictor. So, you will be using a one bit and use result from last time this instruction executed and small memory indexed by the lower bits of the branch instruction. So, what is being done? Suppose you have got a, this is the address corresponding to a branch instruction and this may be 32 bit. So, what can be done? May be 4 bit or 8 bit will be used to index a small memory, where this will index a memory and where you will store that single bit. That means it will be 0 or 1, this is the 0 corresponds to untaken or not taken and this corresponds to taken. So, you can see you are storing one bit corresponding to each branch address that has been encountered and this is used for indexing purpose. So, this is a kind of cache memory. Later on I shall discuss about the cache memory in details, there you will see there also the lower order address bits are used to as an index and to 0.2 memory locations. So, here also the same thing is being done and however you are storing only a single bit of information t or nt and starts off as t. So, that means initially initial value is usually and it flips whenever a branch behaves opposite to prediction and it benefits from large pipelines particularly whenever you are using a large pipeline then it is benefited. Let us see how it really works. So, you have got using a single bit you have if you look at the state transition diagram of this predictor, it has got two states corresponding to taken, where the value is 1 or not taken or untaken. So, if the outcome is taken then it comes back to this it remains here, but if the prediction turns out to be wrong then if it is not taken then it will go to this state and next time if it is not taken then it will remain here. So, and if it will remain in the not taken state as long as the prediction turns out to be I mean if the branch is not taken and here it will remain in this as long as it is taken. So, whenever it is in taken state if a branch is not taken then it will go to this. On the other hand whenever it is in the not taken state if a branch is taken then it will go to this state. So, this is how this particular thing works and this is the state transition diagram. And as I mentioned for simple pipelines the benefit may not be much. However, whenever you have got very large pipeline say at 12 stages, 10 stages or more then you will be benefited more. Now, let us have a look at the limitations of one bit predictor. Now, prediction value may not correspond to the branch being considered. So, this is a very interesting observation, see here it is being said that prediction value may not correspond to a branch being considered. Say what we are doing? We are indexing by using the 8 bit address. So, this is a branch address corresponding to a branch instruction. Now, there may be another branch instruction giving the same bits that means, same lower order 8 bit. So, this will also point to the same location. Now, what may what can happen? This particular we are trying to predict when the branch address is this. I mean the instruction address corresponding to correspond to this, but the value which is being stored here corresponds to this branch instruction. So, what is happening? We are trying to predict from the lower order address which may have come from some other branch. The main flaw here is you see normally in a cache memory we have tagged bits. Later on I shall discuss in detail in that case you know what is being done in case of conventional cache memory, you have this is the different fields of the cache memory. So, here it has got two parts, one is your tag and another is your data and of course, there are few flag bits which I am not showing valid and another thing. Now, these tag bits are missing in this particular cache. So, although we are using cache memory, but tags without tags that means without tag bits. What is done by the tag bit? The higher order address is stored in the tag bit. So, whenever I mean if the pointing is done with the help of this lower order address, then higher order address is compared with the tag value that is being stored. So, in such a situation the problem that is arising here will not occur. That means, since our cache is without tag, so it will be always hit and in case of conventional cache memory, it is not always hit. That means, only when the higher order address is same as the tag bits, so these two has to be same, only then there is a hit. So, this higher order address is compared with this tag and only when they are same there is a hit, but in this particular simple situation there is no tag bit, so it is always hit and this problem is arising out of this. So, this information value may not correspond to branch being considered. So, as I have already mentioned, this cannot be avoided because branch prediction buffer serves as a cache without tags. So, we are holding the information in branch prediction buffer which is acting as a cache memory without tags. Now, let us consider some examples. Consider a loop which is looping 10 times and repeated executions of the loop will result in two incorrect predictions. So, first iteration flips not taken to taken and last iteration flips from taken to not taken. So, at least I mean there will be two mispredictions. So, two misprediction and out of 10 and so the prediction accuracy is 80% in such a case. Now, if the branch alternates between taken and not taken what can happen? A particular program branch is for a particular branch address it is alternately changing taken not taken, taken not taken. So, whenever we use one bit then what will happen? The prediction accuracy will be 0 because you will predict taken but it is not taken. So, you will modify it to not taken next time. So, this is actual and this is predicted. So, predicted is taken actually not taken. So, you have modified it to not taken and again it will be taken. That means if it alternates it will continue and taken it will be not taken. So, what will happen? The misprediction rate is very high 100%. So, we get 0% accuracy. So, this is the limitations of one bit predictor and this is another example. So, actual outcome of branches is not taken, not taken, not taken, taken, taken, taken. So, this is how I mean for a particular application this happens. So, initially it was taken because previous branch was not taken. So, it was modified to not taken. So, it matches matching here. So, previous one was not taken. So, it is not taken here. It is matching here but here previous value was not taken but now it is taken. So, this is incorrect. This is a wrong prediction. So, previous was taken. So, here it is taken. So, here it is again matching. So, we find that in this case there are two wrong which are shown by red color and four correct. So, there is 60% of accuracy. Now, how can we improve this prediction? So, instead of a single bit we can go for two bit predictor which can do even better. So, of course this is a special case of K bit predictor. We can have K bit in our predictor but for the sake of simplicity we shall consider two bit predictor and we shall see how this two bit predictor performs and whether later on we shall also see by increasing the number of bits whether there is any benefit or not. So, change prediction only if twice mispredicted. So, incremented if taken, decremented if not taken. So, this is the basic idea of two bit dynamic branch prediction scheme. So, it is done in this way. So, suppose since you are using two bits it will have four states. Let us assume the lower two states correspond to predict not taken and the top one corresponds to predict taken. And whenever let us start with this state 0 0 we shall be having two bits. Now, whenever predict here the prediction is predict not taken and if it is not taken it will keep on looping not taken and if it is taken it is incremented by one. So, it goes to this state. So, here it is 0 1 now if it is again not taken it comes back to this state that means it is decremented when not taken and incremented when taken. So, when taken it is incremented now if it is taken then it will go to this taken and not taken we have already taken care of. Now, it will go to taken means it will increment by one. So, it will become 1 0 in this particular case if it is not taken again it will come back here it is it will be decremented and if it is taken it will go to this state taken if it is not taken I mean go to this state we will with value 1 1 and if it is not taken it will come back here. So, we find that the for a this is the case for two bit predictor in general we can have n bit predictor. In a n bit predictor the number of states can be starting from 0 1 up to 2 to the power n minus 1. So, in case of two bit it is 0 1 2 and 3. So, these are the states then we see that it is incremented whenever it is taken and it is decremented whenever it is not taken. So, we can start with this or we can start with this that can be our initial point. So, here if it is taken it will remain here. Now, this we are realizing with the help of a saturating counter what is the difference between a saturating ordinary counter and saturating counter the difference lies in this as we know in case of ordinary counter it starts incrementing from 0 then 1 then 2 in this way it will go up to 2 to the power n minus 1 that means that will correspond to all 1 then again it will come back to 0. So, that is the conventional counter, but here it is not so as you can see whenever it is incrementing after if you whenever it reaches the value 2 to the power n minus 1 it remains here that means if it is taken continuously it will remain here it will not it will saturate at that point. Similarly, if you keep on decrementing whenever it is not taken it will reach the point 0 and it will remain in that as long as it is not taken. So, this is called saturating counter and when the value is half of 2 to the power n minus 1 or half or more then it is taken and it is less than half then it is not taken. So, there is a boundary as you can see the upper half corresponds to predict taken and lower half corresponds to predict not taken. So, whenever it switches between these two it changes between taken and not taken. So, this is how it works in general for n bit counter and for a 2 bit predictor this is how it works. So, this is a 2 bit predictor as I have mentioned this is a special case of n bit saturating counter and it can take on values between 0 to 2 to the power n minus 1 when the counter is greater than or equal to half of the 1 half of the 1 half of the max value predict is taken otherwise predict is not taken as I have already mentioned. So, this is your 2 bit predictor and here also the branch prediction buffer is implemented as a special cache as I have already mentioned. This you are storing the bit values in a cache memory that branch predictor buffer and this is accessed due to instruction phase stage. You can see this cache memory is accessed by at the instruction phase stage and again lower order address values are used for as a pointer. So, lower order address these are the lower order address bits which are used as pointer and which is these are the predicted values 1110 depending on those states that I have already mentioned that means 1001. So, 11101110 these values are being stored that predicted values are stored here corresponding to different I mean instructions corresponding to branches. Now, let us look at the performance of this 2 bit predictor. What is the predictor accuracy using a 4096 entry 2 bit branch predictor for a typical application and it has been found that 99 percent to 80 percent depending upon the application. So, it will depend on the application program. So, from one application to another application it will vary but prediction accuracy appears to be quite good it is 99 to 80 percent. Now, as I mentioned there is a scope for increasing the number of bits in the predictor. Now, question naturally arises what is the optimum number of bits that should be used in the predictor whether 2 bit is sufficient or 3 bit is better than that significantly better than that or 4 bit is significantly better than that. So, what is the optimum number of bits that should be used for predicting and it has been found that 2 bit predictors do almost as well as n bit predictors I shall show you the statistics for application programs. Another scope is can the accuracy of branch prediction be improved. So, there are two ways by which you can improve the performance. One is by increasing the size of the branch target buffer another is by using a better prediction scheme. So, later on we shall see how the accuracy of the branch prediction can be improved. So, first let us see what is the improvement as we increase the number of bits. So, it has been considered for SPAC 89 bench max using 4096 entry 2 bit predictor buffer. So, the study was performed long back back in 1992 by Panso and Rame. So, here you can see this is the frequency of mispredictions for different programs. So, mispredictions as you can see varies from 18 percent to 0 percent. So, for this particular problem application EQN TOTT I do not know exactly what is this application, but for this application the misprediction rate is very high. So, you can see the frequency of misprediction is dependent on the application. Now, let us compare this with that of unlimited number of bits that is unlimited number of entry that you have got. So, here you have got only 4096 entry. Now, if you increase the number of entries unlimited entries 2 bit entries unlimited number of 2 bit entries what is the frequency of misprediction. As we can find in most of the cases there is some improvement, but very small. For example, for unlimited entries NASA 7 example gives 0 percent misprediction. On the other hand with 4096 entries 2 bit entry gives 1 percent misprediction. And if we consider the another example GCC here there is a decrease of only 1 percent of misprediction. So, we find that there is marginal or no increase in performance as we increase the size of the buffer. So, from this what conclusion we can make? The conclusion that we can make is that 4096 bit is quite sufficient. There is no need to increase the size of the branch prediction buffer to achieve better performance. Now, we shall consider about better schemes. So, we have seen by increasing the size of the buffer we are not gaining much. So, what is the other alternative? Other alternative is to use a better scheme, better scheme than this 2 bit predictor. So, the better scheme that has been proposed one of them is known as correlating branch predictor. So, this 2 bit predictor uses only the recent behavior of a single branch to predict its future behavior. So, what we are doing here? What happened in the recent past? That information is being used to predict the future. Obviously, it is not performing well. So, what can be done? It may be possible to improve the accuracy of branch prediction by using branch predictors that use the behavior of other branches to make the prediction. These are known as correlating predictors or two level predictors. So, there may be more than one branch in a program. It is quite obvious. So, so far we have restricted to the present branch instruction. Now, what happened to the present branch instruction? Now, what we are trying to do? We are trying to look at other branches and let us see whether other branches affects the current branch. That means, we are looking at the behavior of other branches to make the prediction and this is known as correlating predictor or two level predictor. So, let us look at this example on the left side. If A is equal to 2, then B is equal to 2. So, these are variables. If A is equal to 2, then B is equal to 2 and if B is equal to 2, then B is equal to 0. And if A is not equal to B, then something. So, this is the example and whenever we go for this MIPS instruction, assembly language instruction and assembly language program corresponding to this high level language program, we get this. And here, these A and B are considered these variables A and B are being stored in register R 1 and R 2. So, then here what we are doing? D sub u. So, you are subtracting 2 from R 1, then storing in R 3. Then we are comparing B not equal to Z R 3. This is a branch instruction and R 3 is compared whether branch if it is not equal to 0, then it branches to L 1. If it is equal, then it executes the next instruction. And similarly, that B is also stored in R 2. So, here we are subtracting 2 from R 2, storing in R 3. Again, if we are comparing it with equal to 0 and that R 3 whether it is 0 or not, we branch not equal to 0. If it is not equal to 0, it branches to L 2 and this is the target address L 2. Otherwise, it executes d add R 2 comma R 0 comma R 2. And this is the L 2 branch and third branch is B 3 that this is this one. If it is not equal to B equal to 0, so that means this if it is not equal to B, then it branches to L 3. So, this is the assembly language program. Here, the important observation from this example is that behavior of B 3, so whether that branch will be taken or not taken is dependent on is B 3 can be correlated with that of B 1 and B 2. That means, what happened in B 1 and B 2 is affecting B 3. That means, if both B 1 and B 2 are not taken, then B 3 will be taken. So, this is the important observation of this correlating branch predictor. That means, if both B 1 and B 2 are not taken, then B 3 will be taken. So, this important observation can be used in the prediction in a correlating branch predictor. So, information about previous two branches can be used to predict the behavior of B 3. That is the basic idea of the correlating branch predictor. And this is a generalization of correlating branch predictor. So, here an m comma n predictor that makes use of outcomes of the observed from the last m branches. So, there may be m branches and those m branches can be taken or not taken that will lead to 2 to the power m alternatives. So, previous m branches each of them may be taken or not taken. So, this bit can be 0 or 1. So, that means, it has got m bits and each bit can be if it is all or not taken, then it can be 0 and the corresponding m bit if all are taken, then it can be all 1. So, you can see you have got 2 to the power m possibilities whenever you consider m outcomes of the previous m branches. And behavior of a branch can be predicted by choosing from 2 to the power m branch predictors. It is improved prediction accuracy for small hardware cost. So, we shall see what is the hardware cost involved in it. And history of the last m branches can be kept in a as a SIFT register. So, this is how the information of m branches can be kept and each bit records whether corresponding branch was taken or not taken as I have already told. If it is taken, it will be 0. If it is not taken, it will be 1. If it is not taken, it will be 0. And branch prediction buffer can then be indexed by the concatenating the lower order bits of the address with the m bit history. So, this m bit history and the lower order bit address of the instruction can be used as a pointer, can be indexed by the concatenating index by this. So, let me show it, how it can be done with the help of a 2, 2 correlating predictor. So, in this particular case, we are using 4 bit, 4 lower order bit of the address. Then we are considering m is equal to 2, m is equal to 2 means it will be having, there are possibility of 4 alternatives. Previous two branches can have 4 alternatives 0, 0, 0, 1, 1, 0, 1, 1. And the 2 bits that is being stored are taken, not taken, which are stored here. That 2 bit, we have seen whenever we are using 2 bit, then it will require 4 states 0, 0, 0, 1, 0, 2, 1, 1, 1. And this is being stored in this particular memory. So, for this purpose of visualization, these are shown separately, but they can be stored in a linear manner in the memory. So, here you can see, the branch address is pointing to a particular location. And with the help of this index, you can have one of the 4. That means, in this case m is equal to 2, there are 4 possible alternatives. And the 2 bit global branch history is pointing to one of these 4. So, that means that global branch history means that previous 2 branches, whether both of them were taken or both of them were not taken, one was taken, another was not taken. That history is being used and that is pointing to one of the 4 possible columns. So, we have got 60 to 64 total number of entries, and out of which you can see 1 out of 16 is pointed out by the band address. And again 1 out of these 4 is pointed by the 2 bit global branch history. And this is how the prediction xx that is your 2 bit prediction is available from here and which is being used for the purpose of branch prediction. So, a 2, 2 buffer with 64 total entries is shown here for lower address bits of the branch and 2 global orbits from the index. So, for the purpose of visualization it is shown here, but it may be considered as a single entry. That means, you can have 6 bit, 4 bit, this is the lower order bit address and the higher order bit can be address can be coming from branch history. So, this will be acting as a pointer in such a case, it can be linear memory. So, there will be 64 entries starting from all 0 to all 1 and each having 2 bits. So, this is how the branch target buffer can be organized and the information about the correlating predictor can be stored in this branch target buffer. And let us see what kind of prediction accuracy is obtained with the help of this particular type of entry, I mean whenever we use this correlating predictor. This was done for this sake of comparison, the comparison should be done on equal footing. That means, you see we are comparing this correlating predictor with the 2 bit predictor. In case of correlating predictor, you have got the memory requirement that is in the branch target buffer has to be same as that of 2 bit predictor, only then the comparison will be on equal footing. That is what has been tried here. For example, the number of bits in 4096 entries in a 2 bit predictor is 8 k. So, with the same number of memory for 1 0 to 2 4 entries here there is a mistake it will be 2 into 2 into 1 0 to 4, 2 into 2 into 2 that means for 1 0 to 4 entries and 2 bit predictor and here it will be 2 bit for that the number of that m and n that is varying that varies. So, it will be 1 0 to 4 into 8, so that will give you 8 k. So, with the same number of bits the comparison is being done and this is the 4096 entry, 2 bit entry and unlimited entry and 1 0 to 4 entries that is your correlating predictor 2, 2. So, here as you can see there is significant improvement in performance for the last curve. This corresponds to the correlating predictor. So, here you can see there is some decrease for some applications. So, from 9 percent it is coming down to 5 percent for the same size of branch target buffer, branch prediction buffer. Here also coming down from 9 to 5 for application a PPP from 9 percent to 5 percent and for GCC it is coming down from 12 to 11 percent it is same as the case where you have got unlimited buffer. So, comparison between whenever we go for unlimited buffer with that it is performing same with limited buffer that means with 8 k entries 8 kilo bits. So, again here we are getting a decrease of 5 to 4 to 4, but here there is a dramatic improvement of performance. We have seen for this example EQ and TOTT for limited buffer of 8 k and 8 kilo bit and for unlimited buffer it was 8 kilo bits 18 percent, but as you can see here for correlating predictor it is coming down to 6 percent. So, this is there is a significant improvement in performance of this correlating predictor. And similarly for LI application it is coming down from 10 percent to 5 percent. So, what we can say from this our conclusion is this correlating predictors perform better compared to 2 bit predictor with limited branch target branch prediction buffer and also with unlimited branch prediction buffer. So, that is the reason why this particular approach has been found to be attractive. Now, the question arises we have already seen how this correlating branch predictor works and what we are trying to do we are noting down the predictions of other branches or rather the predictions for other branches are being used for I mean the outcome of other branches are being used to predict the behavior of the present branch. In what way I mean why it is possible and how it is possible that you should understand and why does the outcome of one branch depend on the outcome of another branch. So, we are considering other branches to predict the behavior of the present branch why this is so. The reason for that is depending on whether some preceding branch is taken or not taken some variable may be set to some value or not. So, what is happening you know some variables are propagating from one branch to another branch and values are modified by the previous branches and which are being used by the present branch and this is how one branch is affecting another branch and that is the reason why this correlating branch prediction is working better compared to the based on the local branch. So, here there is another example of correlating branch prediction example this is d is equal to 2 if d is equal to 0 then d is equal to 1 if d is equal to 1 then d is equal to 0 else d is equal to 2 and so on. So, this is a simple example and the corresponding assembly language program is shown here branch not equal to 0 r 1 comma l 1 that means branch is taking place if d is not equal to 0 and here branch is taking place if d is not equal to 1. So, b 1 is not taken then b 2 will not be taken. So, you see because of the variable that is passing with that d that variable value is passing from one branch to another branch and from if b 1 is not taken then b 2 will not be taken because d 1 this that the variable d is being modified by previous branch and that is being used by subsequent branch decision and that is the reason why this correlating branch predictor is performing well. And from this in this particular example for example, if b 1 is not taken then b 2 will not be taken. So, let us consider situation where we shall be considering one bit predictor for the example. This is the example that we are considering how this example behaves for one bit predictor. So, the value of d is changing alternately it is becoming 2 and 0 2 and 0 and that b 1 prediction is not taken not taken taken I mean if you substitute it here you will get this outcome. This is the prediction initially not taken. So, initially not taken then actually it was taken. So, that was changed to taken but unfortunately next time it is not taken. So, this is the new b 1 prediction and that is not matching and again it was not taken. So, it was changed to not taken. So, prediction was not taken but it was actually taken. So, this was the case for branch b 1 and in case of branch b 2 again initially it was not taken but actually it was taken. So, it was modified to taken but unfortunately next time again it was not taken and again not taken. So, not taken there was a prediction but actually it was taken. So, this prediction was changed to taken and unfortunately next time again it was not taken. So, in this particular case we find that for one bit predictor prediction accuracy is 0 percent because if you consider the first table I mean second column not taken not taken taken corresponding the value of d is equal to 2 0 2 0 and with the initialization I mean initial value of n t this is the prediction and actually just the opposite for all the four cases. Similarly, here for the branch b 2 the prediction was not taken taken not taken and taken and actually it was taken not taken taken not taken. So, again it was the prediction accuracy was 0 percent I mean always wrong. So, we find that one bit predictor for this example for this particular example and for these two values of d alternate values of 2 and 0 or prediction accuracy is 0. Now, let us see how this 1 comma n that is m is equal to 1 and n is equal to 1. So, this is a correlating predictor and we shall apply this to for a simple correlating predictor having 1 m is equal to 1 and n is equal to 1 and here it has got two bits prediction if last branch not taken and prediction if last branch taken. So, we are using two bits and it is initialized to not taken not taken. So, in this particular case as the values of d changes from 2 2 0 2 2 0 the B 1 prediction was not taken not taken and but actually it was taken. So, it was modified and the new branch prediction was taken slash not taken and it was next time it was taken not taken but it was not taken. So, this is the prediction this is the prediction and in this way you can show all the corresponding to this branch. We find that only for the first row not taken not taken and here it is taken and except for this first row here also we find that for B 2 prediction not taken not taken it was taken so it was changed to not taken by taken. So, this corresponds to the first one corresponds to B 1 second one corresponds to B 2. So, we find here that except the first row for all other cases prediction is correct. That means here it is taken not taken here also taken not taken taken not taken taken slash not taken same taken slash not taken taken slash not taken. Similarly, the second row here not taken by taken not taken by taken not taken by taken not taken by taken. So, here except the first row for all other cases we are finding that prediction accuracy is correct that means prediction is correct. So, we can say that prediction accuracy is nearly 100 percent for subsequent cases. Let us talk here today with this correlating branch predictor. In the next lecture we shall discuss about another important predictor that is known as tournament predictor. And you know when some games are proceeding for example, a game of cricket prediction is done. So, normally prediction is done in two ways say out of so many matches 100 matches how many match a particular team own. Another comparison is done on this particular ground so many matches took place and in those so many matches how many matches a particular team own. So, we can see here one parameter is global another parameter is local. So, this local and global parameters are used in tournament prediction. Somewhat similar concept is being used in the tournament predictor that I shall be discussing in the next lecture. Thank you.