4 ms·
Oh, I thought the uop queues were uop caches when I looked at the diagram. Not having loop handling does seem off, but I guess with long loops they will just a
by pclmulqdq 2y ago
Oh, I thought the uop queues were uop caches when I looked at the diagram. Not having loop handling does seem off, but I guess with long loops they will just alternate between the decoders.
The whole 99% branch prediction thing is sort of misleading - most branches are loops taken for a constant amount of time, so most are perfectly predictable, and most others are error checks which are also easy to predict. However, a large amount of comparative wall time in code is spent on sequences of a short piece of code and a branch that is hard to predict. Without hyperthreading, I would assume that decoding both sides of the branch would actually help a lot in these circumstances. It sounds like Intel is possibly capable of doing that.
The synthetic basic blocks are also an interesting idea given how hard it is to figure out where an x86 instruction boundary is. It's easy to split a basic block when you have a branch going to that basic block, but if you just synthetically insert a split some distance down, you may be misaligned with the actual instruction stream. That can be self-synchronizing at points, but it's hard.
- vlovich123 2y agoBranches that are hard to predict should be “hand-optimized” through specially written code, compiler intrinsics/annotations, or profile guided feedback to tell the compiler to emit the conditional using unconditional branchless instructions like cmov. Expecting a CPU to detect this at runtime may be asking it to do too much.
- pclmulqdq 2y agoThat necessitates executing both sides fully. Very often, those are "business logic" branches that are very long, and you would only prefer to cover branch mispredict penalty.
- vlovich123 2y agoYes you would only do this for hot loops that have short basic block branches (binary search being the canonical example). That’s why I said hand annotate vs having the CPU try to detect and distinguish these situations at runtime.
- pclmulqdq 2y agoYes, we're talking about different things. Those are able to be optimized in software doing what you mentioned. The branches I am talking about are not. They often sit in "business logic" code.
- vlovich123 2y agoYeah but business logic code like that isn’t generally bounded by the misprediction penalty so it doesn’t matter.
- phire 2y ago> Not having loop handling does seem off I do agree. The fact that those uop queues are already there and Intel isn't using them as a loop buffer does make me ask questions. Have they just not gotten around to it? Have they decided its not worth the power savings? Maybe they are aiming for simplicity? > However, a large amount of comparative wall time in code is spent on sequences of a short piece of code and a branch that is hard to predict. The thing is, any time the branch predictor has at least one correct prediction, the decode throughput doubles to 6 IPC. And if it gets two correct predictions in a row, the IPC triples to 9. I'm not sure how many cycles the "execute both sides of the branch" would save on a misspredict, but your basic blocks would need to be very short and the prediction accuracy would need to be very low (like, 50% or lower) before it can actually out-preform the leapfrogging decoder approach on those sequences of code. > but if you just synthetically insert a split some distance down, you may be misaligned with the actual instruction stream It only inserts the splits after decoding, so they will always be at the correct alignment.
- pclmulqdq 2y ago50% is about as bad as you can get without code that is specifically pathological - that is random guessing.