 In contrast to the static branch predictors, dynamic branch predictors will look at what the code has actually been doing while it's running. We'll be looking at three different general types of branch predictors. The MN branch predictors are the simplest. Those will just focus on keeping track of what happened the last time this branch ran. Venture ones may include what happened the last two to three times that this branch ran, but they're really just focused on keeping track of what happens with this specific branch and won't take any of the other context into account. Returnment branch predictors have a few options. They could choose to select one of those MN branch predictors. It could choose to select a global branch predictor, or it could decide to potentially select a static branch predictor, depending on which instruction it's running. The idea here is that one of these methods may be better for a given instruction than another, and we'll try to pick the one that works best for this branch in particular. Perceptron branch predictors are actually popular in modern hardware. In this case, instead of just looking at the branch, we can zoom out and look at some of the surrounding code as well. We can start to get an idea about what some of those other instructions are doing in our code and how that's going to affect the results of our branch instruction. Dynamic branch predictors end up being really popular because they increase the accuracy of our branch prediction substantially. In some cases, we can even get above 90% accuracy. The result is a whole lot fewer NO-Ops going through our pipeline because of unexpected branches.