LWN: Comments on "Likely unlikely()s" https://lwn.net/Articles/420019/ This is a special feed containing comments posted to the individual LWN article titled "Likely unlikely()s". en-us Sun, 05 Oct 2025 14:47:20 +0000 Sun, 05 Oct 2025 14:47:20 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Likely unlikely()s https://lwn.net/Articles/421098/ https://lwn.net/Articles/421098/ tesarik <div class="FormattedComment"> *the* compiler? which compiler?<br> <p> Surely, gcc heuristic decisions change with the version...<br> </div> Mon, 27 Dec 2010 11:00:33 +0000 Likely unlikely()s https://lwn.net/Articles/421097/ https://lwn.net/Articles/421097/ tesarik <div class="FormattedComment"> Well, let's give a better example of this. Consider a spinlock slow<br> path (ie. on contention):<br> <p> while(unlikely(is_locked(lock)))<br> cpu_relax();<br> <p> Although it's likely that the lock is held many times before we can take it,<br> it's more important to run the critical section as fast as possible when it<br> finally gets available.<br> <p> </div> Mon, 27 Dec 2010 10:54:12 +0000 Likely unlikely()s https://lwn.net/Articles/420591/ https://lwn.net/Articles/420591/ vonbrand <p> It has been observed that programmers are <em>terrible</em> at guessing where their programs spend most of their time... and that should be much easier than predicting the frequency of some critical branch going one way or the other. <p> Best leave it alone, or only annotate when extensive measurements show a high bias (and the compiler gets it wrong). Tue, 21 Dec 2010 13:58:31 +0000 Likely unlikely()s https://lwn.net/Articles/420530/ https://lwn.net/Articles/420530/ jzbiciak <P>I did state my model was simplified, and did allow for the fact that branch prediction could change the cost over time and that that wasn't included in my model.</P> <P>My understanding is that static prediction mainly involves either putting a hint on a branch opcode (on architectures that support it) and/or changing which path is the "fall through" path versus the "branch taken" path, overlaid with a rule such as "predict backward branches as taken; forward branches not-taken". In the presence of dynamic prediction, a branch hint should be just that: a <I>hint</I>. A strong prediction signal from the predictor ought to override a hint.</P> <P>The main purpose of branch hinting is to help the cold-predictor case. <A HREF="http://arstechnica.com/old/content/2001/05/p4andg4e.ars/4">This article describes one such scheme.</A> Basically, if your branch isn't in the Branch History Table (BHT), then it falls back to the static prediction. This puts an upper bound on how much damage the static prediction can do, as well as an upper bound on how much it can help.</P> <P>For static branch prediction to hurt, you'd need to have a large enough working set that the branch in question isn't in the BHT (to use the P4's scheme above), but still hit often enough to make a measurable performance difference.</P> <P>For your bimodal case (day/night shifting patterns), which ever way you schedule your code, you'll penalize one or the other. If you have accurate long-term branch statistics, though, you can still pick the one that occurs less often and penalize that. So, if daytime has twice the load as nighttime, it should show up in the statistics and you can put <TT>likely/unlikely</TT> on the conditional to favor daytime.</P> <P>Really, the argument that makes the most sense to me against <TT>likely/unlikely</TT> in marginal cases is that different users could have completely different workloads with wildly different statistics (multimodal across all users, even though each user might be unimodal), and so there's no good training set, so just let the compiler guess. There's no way to avoid penalizing someone, so let the compiler do it. Only put <TT>likely/unlikely</TT> where it's clear that it's right across the vast majority of workloads. Otherwise, there's a good chance it could be wrong for more than half the users out there, and it's also not worth the maintenance burden.</P> <P>So, that leaves the question: What's the criteria for figuring that out? Taken vs. not-taken ratio seems like a shaky heuristic to me.</P> Mon, 20 Dec 2010 20:35:35 +0000 Likely unlikely()s https://lwn.net/Articles/420425/ https://lwn.net/Articles/420425/ quotemstr You're assuming that p<sub>correct</sub> and p<sub>incorrect</sub> are constant over time, and they're often not. CPUs these days have large global branch prediction buffers and can detect fairly complex patterns (e.g., branch every third time) automatically. The overall result of this dynamic prediction may be superior to a purely static assertion, even if that assertion is correct on <i>average</i>. <p> Think of a branch that goes one way during the day and another way at night. If we suppose that activity is twice as high during the day, then we'll see a 2:1 branch bias in favor of the daylight path. But over smaller intervals of time (say, an hour), the branch bias will be almost totally in favor of one path or the other. Unlike static assertions, the CPU's automatic prediction can look at the specific circumstances of the system and make predictions based on recent behavior and specific circumstances. Using static branch prediction could actually hurt. Sun, 19 Dec 2010 03:39:48 +0000 Likely unlikely()s https://lwn.net/Articles/420412/ https://lwn.net/Articles/420412/ giraffedata <p> <b>dmk</b>'s basic idea seems valuable, but the example is bad. And <b>cras</b> seems to have misread that example. We need a better example. <p> The problem with what <b>dmk</b> writes ("we would want to get the decision really fast") is that likely() doesn't affect how fast the test is. It affects how fast what you do as a result of that test is. If the test is <i>world_continues</i> and you want to respond quickly when it does, then the truth is the right way to go: <i>world_continues</i> is likely, and that's how you want to annotate it. <p> I believe <b>cras</b> assumes we want to respond quickly if the world is ending, because it isn't really ending -- we can save it. That's not what <b>dmk</b> described: he said the world really is ending, so all we can do is say good bye, and it just won't make any difference how slowly we do that. Sat, 18 Dec 2010 20:54:16 +0000 Likely unlikely()s https://lwn.net/Articles/420227/ https://lwn.net/Articles/420227/ cras <div class="FormattedComment"> Of course. But if there are some heavily used macros and functions where it's easy to add them once and then get them used throughout the code, it's not much extra trouble even if the benefit is small.<br> <p> Although now that I think about it, maybe many of those checks I used to put unlikely() in my code are nowadays pointless, because they call functions that I've since marked with __attribute__((cold)), which should put the unlikely()s there automatically. (But do they? I remember testing that the cold attribute did nothing in some gcc version.)<br> <p> </div> Thu, 16 Dec 2010 20:21:27 +0000 Likely unlikely()s https://lwn.net/Articles/420223/ https://lwn.net/Articles/420223/ vonbrand <p> Sounds nonsensical to me... if the annotated code is not in any way performance critical, doing the extra work of annotating it is pure waste. Thu, 16 Dec 2010 19:44:56 +0000 Likely unlikely()s https://lwn.net/Articles/420154/ https://lwn.net/Articles/420154/ Yorick <div class="FormattedComment"> I have heard that story been told in conjunction with the FORTRAN's original FREQUENCY statement, which allegely was dropped because of this (and because humans turned out to be bad at estimating branch frequencies in general). Anyway, I cannot seem to find a source for this either.<br> </div> Thu, 16 Dec 2010 14:45:27 +0000 Likely unlikely()s https://lwn.net/Articles/420140/ https://lwn.net/Articles/420140/ cras <div class="FormattedComment"> Well, if the code was like:<br> <p> while (likely(!is_world_ending()) {<br> update_world_status();<br> }<br> save_the_world();<br> <p> And the branch prediction was wrong pretty much always, that would also increase the amount of time used to update world status. So even when it finally sees the world ending and jumps immediately to saving the world, perhaps it could have done that in the previous iteration already if the inner loop had been faster.<br> <p> Or something like that :)<br> </div> Thu, 16 Dec 2010 13:58:22 +0000 Likely unlikely()s https://lwn.net/Articles/420137/ https://lwn.net/Articles/420137/ dmk <div class="FormattedComment"> wouldn't it be worthwhile sometimes, to annotate a codepath with likely(), even if it wasn't true in reality, just to make that one codepath fast? For example if we are in that one codepath that decides if the world continues or not, we would want to get the decision really fast, if the world continues, else we don't care? <br> <p> <p> </div> Thu, 16 Dec 2010 13:45:24 +0000 Likely unlikely()s https://lwn.net/Articles/420099/ https://lwn.net/Articles/420099/ cras <div class="FormattedComment"> I was once adding likely()s and unlikely()s to heavily CPU-intensive code. I remember that adding unlikely() to a branch that was rarely executed (IIRC only a few % of calls) was slower than simply not giving any hint. Nowadays I add them only to branches where getting the branch prediction wrong just doesn't matter (error handling mostly).<br> <p> </div> Thu, 16 Dec 2010 06:51:43 +0000 Likely unlikely()s https://lwn.net/Articles/420090/ https://lwn.net/Articles/420090/ jzbiciak <BLOCKQUOTE><I>Being wrong 39% of the time was pretty obviously too much and led to the removal of the annotation for that test.</I></BLOCKQUOTE> <P>What that's saying is that a 60:40 ratio is too close. So what <I>is</I> an appropriate threshold? </P><P> It seems like any notable bias in a particular direction should be reason enough. The main key is whether the bias is stable over a range of reasonable workloads. (Note I say "reasonable". If you have <TT>likely(<I>doesn't segfault</I>)</TT> and then run a workload full of segfaults, well that's just silly.) </P><P> Consider a simplified model: You have two costs, k<sub>correct</sub> and k<sub>incorrect</sub>. If you predict a branch is taken and the branch is in fact taken, then you get charged k<sub>correct</sub>, otherwise you get charged k<sub>incorrect</sub>. And, this whole exercise is only worthwhile if k<sub>correct</sub> &lt; k<sub>incorrect</sub>. You also have two probabilities: p<sub>correct</sub> is the probability that your prediction matches what the computer did, and (1 - p<sub>correct</sub>) is the probability it didn't. In this model, then, overall performance should approach k<sub>correct</sub> * p<sub>correct</sub> + k<sub>incorrect</sub> * (1 - p<sub>correct</sub>) if you annotated your branch correctly. In the 60:40 example from the article, p<sub>correct</sub> would be 0.6.</P> <P>In this model, you end up with a few possibilities:</P> <OL><LI>You annotated your branch correctly, and performance = k<sub>correct</sub> * p<sub>correct</sub> + k<sub>incorrect</sub> * (1 - p<sub>correct</sub>) <LI>You annotated your branch <B>in</B>correctly, effectively switching k<sub>correct</sub> and k<sub>incorrect</sub>. performance = k<sub>incorrect</sub> * p<sub>correct</sub> + k<sub>correct</sub> * (1 - p<sub>correct</sub>) <LI>You left it up to the compiler to figure it out. Whether you get #1 or #2 above depends on how good/lucky your compiler is. </OL> <P>Now you're left weighing the quality of the compiler against your ability to get the annotation right and your desire to maintain that annotation. And that's just with this simplified model. In a more complex model, the probability a branch gets taken can vary on other factors, some of which may be discoverable by the CPU's branch prediction logic for example.</P> <P>Given all that, I can see why you'd want a very clear signal for 'likely'/'unlikely'. But still, how clear?</P> Thu, 16 Dec 2010 05:09:53 +0000 Likely unlikely()s https://lwn.net/Articles/420091/ https://lwn.net/Articles/420091/ JoeBuck I recall that there was once a compiler that implemented the user-specified branch likelihood hint backwards and it was at least a year before anyone noticed, but this may be an apocryphal story. Does anyone remember? Thu, 16 Dec 2010 04:53:36 +0000