you have more faith in the authors knowledge of how his code actually behaves than I think is warranted :)
iirc there was a mm patch some time ago to keep track of the actual unlikely
values at runtime and it showed indeed some wrong ones. But the
far majority of them are probably correct.
Or faith in that he knows what "unlikely" means.
I should write docs about this; but unlikely() means:
1) It happens less than 0.01% of the cases.
2) The compiler couldn't have figured this out by itself
(NULL pointer checks are compiler done already, same for some other conditions)
3) It's a hot codepath where shaving 0.5 cycles (less even on x86) matters
(and the author is ok with taking a 500 cycles hit if he's wrong)
One more thing unlikely() does is to move the unlikely code out of line.
So it should conserve some icache in critical functions, which might
well be worth some more cycles (don't have numbers though).
But overall I agree with you that unlikely is in most cases a bad
idea (and I submitted the original patch introducing it originally @). That is because
it is often used in situations where gcc's default branch prediction
heuristics do would make exactly the same decision
if (unlikely(x == NULL))
is simply totally useless because gcc already assumes all x == NULL
tests are unlikely. I appended some of the builtin heuristics from
a recent gcc source so people can see them.
Note in particular the last predictors; assuming branch ending
with goto, including call, causing early function return or
returning negative constant are not taken. Just these alone
are likely 95+% of the unlikelies in the kernel.
-Andi
/* Use number of loop iterations determined by # of iterations
analysis to set probability. We don't want to use Dempster-Shaffer
theory here, as the predictions is exact. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS, "loop iterations", PROB_ALWAYS,
PRED_FLAG_FIRST_MATCH)
/* Hints dropped by user via __builtin_expect feature. */
DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY,
PRED_FLAG_FIRST_MATCH)
/* Use number of loop iterations guessed by the contents of the loop. */
DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations",
PROB_ALWAYS, PRED_FLAG_FIRST_MATCH)
/* Branch containing goto is probably not taken. */
DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (56), 0)
/* Branch to basic block containing call marked by noreturn attribute. */
DEF_PREDICTOR (PRED_NORETURN, "noreturn call", HITRATE (99),
PRED_FLAG_FIRST_MATCH)
/* Branch to basic block containing call marked by cold function attribute. */
DEF_PREDICTOR (PRED_COLD_FUNCTION, "cold function call", HITRATE (99),
PRED_FLAG_FIRST_MATCH)
/* Loopback edge is taken. */
DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", HITRATE (86),
PRED_FLAG_FIRST_MATCH)
/* Edge causing loop to terminate is probably not taken. */
DEF_PREDICTOR (PRED_LOOP_EXIT, "loop exit", HITRATE (91),
PRED_FLAG_FIRST_MATCH)
/* Pointers are usually not NULL. */
DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (85), 0)
DEF_PREDICTOR (PRED_TREE_POINTER, "pointer (on trees)", HITRATE (85), 0)
/* NE is probable, EQ not etc... */
DEF_PREDICTOR (PRED_OPCODE_POSITIVE, "opcode values positive", HITRATE (79), 0)
DEF_PREDICTOR (PRED_OPCODE_NONEQUAL, "opcode values nonequal", HITRATE (71), 0)
DEF_PREDICTOR (PRED_FPOPCODE, "fp_opcode", HITRATE (90), 0)
DEF_PREDICTOR (PRED_TREE_OPCODE_POSITIVE, "opcode values positive (on trees)", HITRATE (70), 0)
DEF_PREDICTOR (PRED_TREE_OPCODE_NONEQUAL, "opcode values nonequal (on trees)", HITRATE (69), 0)
DEF_PREDICTOR (PRED_TREE_FPOPCODE, "fp_opcode (on trees)", HITRATE (90), 0)
/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", HITRATE (69), 0)
/* Branch causing function to terminate is probably not taken. */
DEF_PREDICTOR (PRED_TREE_EARLY_RETURN, "early return (on trees)", HITRATE (54), 0)
/* Branch containing goto is probably not taken. */
DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (70), 0)
/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", HITRATE (69), 0)
/* Branch causing function to terminate is probably not taken. */
DEF_PREDICTOR (PRED_TREE_EARLY_RETURN, "early return (on trees)", HITRATE (54), 0)
/* Branch containing goto is probably not taken. */
DEF_PREDICTOR (PRED_GOTO, "goto", HITRATE (70), 0)
/* Branch ending with return constant is probably not taken. */
DEF_PREDICTOR (PRED_CONST_RETURN, "const return", HITRATE (67), 0)
/* Branch ending with return negative constant is probably not taken. */
DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "negative return", HITRATE (96), 0)
/* Branch ending with return; is probably not taken */
DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (96), 0)
/* Branches to a mudflap bounds check are extremely unlikely. */
DEF_PREDICTOR (PRED_MUDFLAP, "mudflap check", PROB_VERY_LIKELY, 0)
From: Nick Piggin <hidden> Date: 2008-02-19 02:35:24
On Tuesday 19 February 2008 01:39, Andi Kleen wrote:
Arjan van de Ven [off-list ref] writes:
quoted
you have more faith in the authors knowledge of how his code actually
behaves than I think is warranted :)
iirc there was a mm patch some time ago to keep track of the actual
unlikely values at runtime and it showed indeed some wrong ones. But the
far majority of them are probably correct.
quoted
Or faith in that he knows what "unlikely" means.
I should write docs about this; but unlikely() means:
1) It happens less than 0.01% of the cases.
2) The compiler couldn't have figured this out by itself
(NULL pointer checks are compiler done already, same for some other
conditions) 3) It's a hot codepath where shaving 0.5 cycles (less even on
x86) matters (and the author is ok with taking a 500 cycles hit if he's
wrong)
One more thing unlikely() does is to move the unlikely code out of line.
So it should conserve some icache in critical functions, which might
well be worth some more cycles (don't have numbers though).
I actually once measured context switching performance in the scheduler,
and removing the unlikely hint for testing RT tasks IIRC gave about 5%
performance drop.
This was on a P4 which is very different from more modern CPUs both in
terms of branch performance characteristics, and icache characteristics.
However, the P4's branch predictor is pretty good, and it should easily
be able to correctly predict the rt_task check if it has enough entries.
So I think much of the savings came from code transformation and movement.
Anyway, it is definitely worthwhile if used correctly.
Actually one thing I don't like about gcc is that I think it still emits
cmovs for likely/unlikely branches, which is silly (the gcc developers
seem to be in love with that instruction). If that goes away, then
branch hints may be even better.
But overall I agree with you that unlikely is in most cases a bad
idea (and I submitted the original patch introducing it originally @). That
is because it is often used in situations where gcc's default branch
prediction heuristics do would make exactly the same decision
if (unlikely(x == NULL))
is simply totally useless because gcc already assumes all x == NULL
tests are unlikely. I appended some of the builtin heuristics from
a recent gcc source so people can see them.
Note in particular the last predictors; assuming branch ending
with goto, including call, causing early function return or
returning negative constant are not taken. Just these alone
are likely 95+% of the unlikelies in the kernel.
Yes, gcc should be able to do pretty good heuristics, considering
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
From: Arjan van de Ven <hidden> Date: 2008-02-19 02:41:45
On Tue, 19 Feb 2008 13:33:53 +1100
Nick Piggin [off-list ref] wrote:
Actually one thing I don't like about gcc is that I think it still
emits cmovs for likely/unlikely branches, which is silly (the gcc
developers seem to be in love with that instruction). If that goes
away, then branch hints may be even better.
only for -Os and only if the result is smaller afaik.
(cmov tends to be a performance loss most of the time so for -O2 and such it
isn't used as far as I know.. it does make for nice small code however ;-)
--
If you want to reach me at my work email, use arjan@linux.intel.com
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
From: Nick Piggin <hidden> Date: 2008-02-19 04:48:04
On Tuesday 19 February 2008 13:40, Arjan van de Ven wrote:
On Tue, 19 Feb 2008 13:33:53 +1100
Nick Piggin [off-list ref] wrote:
quoted
Actually one thing I don't like about gcc is that I think it still
emits cmovs for likely/unlikely branches, which is silly (the gcc
developers seem to be in love with that instruction). If that goes
away, then branch hints may be even better.
only for -Os and only if the result is smaller afaik.
What is your evidence for saying this? Because here, with the latest
kernel and recent gcc-4.3 snapshot, it spits out cmov like crazy even
when compiled with -O2.
npiggin@am:~/usr/src/linux-2.6$ grep cmov kernel/sched.s | wc -l
45
And yes it even does for hinted branches and even at -O2/3
npiggin@am:~/tests$ cat cmov.c
int test(int a, int b)
{
if (__builtin_expect(a < b, 0))
return a;
else
return b;
}
npiggin@am:~/tests$ gcc-4.3 -S -O2 cmov.c
npiggin@am:~/tests$ head -13 cmov.s
.file "cmov.c"
.text
.p2align 4,,15
..globl test
.type test, @function
test:
..LFB2:
cmpl %edi, %esi
cmovle %esi, %edi
movl %edi, %eax
ret
..LFE2:
.size test, .-test
This definitely should be a branch, IMO.
(cmov tends to be a performance loss most of the time so for -O2 and such
it isn't used as far as I know.. it does make for nice small code however
;-)
It shouldn't be hard to work out the cutover point based on how
expensive cmov is, how expensive branch and branch mispredicts are,
and how often the branch is likely to be mispredicted. For an
unpredictable branch, cmov is normally quite a good win even on
modern CPUs. But gcc overuses it I think.
On Tue, Feb 19, 2008 at 01:33:53PM +1100, Nick Piggin wrote:
quoted
Note in particular the last predictors; assuming branch ending
with goto, including call, causing early function return or
returning negative constant are not taken. Just these alone
are likely 95+% of the unlikelies in the kernel.
Yes, gcc should be able to do pretty good heuristics, considering
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
in my experience, the real problem is that gcc does what *it* wants and not
what *you* want. I've been annoyed a lot by the way it coded some loops that
could really be blazingly fast, but which resulted in a ton of branches due
to its predictors. And using unlikely() there was a real mess, because instead
of just hinting the compiler with probabilities to write some linear code for
the *most* common case, it ended up with awful branches everywhere with code
sent far away and even duplicated for some branches.
Sometimes, for performance critical paths, I would like gcc to be dumb and
follow *my* code and not its hard-coded probabilities. For instance, in a
tree traversal, you really know how you want to build your loop. And these
days, it seems like the single method of getting it your way is doing asm,
which obviously is not portable :-(
Maybe one thing we would need would be the ability to assign probabilities
to each branch based on what we expect, so that gcc could build a better
tree keeping most frequently used code tight.
Hmm I've just noticed -fno-guess-branch-probability in the man, I never tried
it.
regards,
Willy
From: Nick Piggin <hidden> Date: 2008-02-19 06:21:22
On Tuesday 19 February 2008 16:58, Willy Tarreau wrote:
On Tue, Feb 19, 2008 at 01:33:53PM +1100, Nick Piggin wrote:
quoted
quoted
Note in particular the last predictors; assuming branch ending
with goto, including call, causing early function return or
returning negative constant are not taken. Just these alone
are likely 95+% of the unlikelies in the kernel.
Yes, gcc should be able to do pretty good heuristics, considering
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
in my experience, the real problem is that gcc does what *it* wants and not
what *you* want. I've been annoyed a lot by the way it coded some loops
that could really be blazingly fast, but which resulted in a ton of
branches due to its predictors. And using unlikely() there was a real mess,
because instead of just hinting the compiler with probabilities to write
some linear code for the *most* common case, it ended up with awful
branches everywhere with code sent far away and even duplicated for some
branches.
Sometimes, for performance critical paths, I would like gcc to be dumb and
follow *my* code and not its hard-coded probabilities. For instance, in a
tree traversal, you really know how you want to build your loop. And these
days, it seems like the single method of getting it your way is doing asm,
which obviously is not portable :-(
Probably all true.
Maybe one thing we would need would be the ability to assign probabilities
to each branch based on what we expect, so that gcc could build a better
tree keeping most frequently used code tight.
I don't know if that would *directly* lead to gcc being smarter. I
think perhaps they probably don't benchmark on code bases that have
much explicit annotation (I'm sure they wouldn't seriously benchmark
any parts of Linux as part of daily development). I think the key is
to continue to use annotations _properly_, and eventually gcc should
go in the right direction if enough code uses it.
And if you have really good examples like it sounds like above, then
I guess that should be reported to gcc?
On Tue, Feb 19, 2008 at 01:33:53PM +1100, Nick Piggin wrote:
On Tuesday 19 February 2008 01:39, Andi Kleen wrote:
quoted
Arjan van de Ven [off-list ref] writes:
quoted
you have more faith in the authors knowledge of how his code actually
behaves than I think is warranted :)
iirc there was a mm patch some time ago to keep track of the actual
unlikely values at runtime and it showed indeed some wrong ones. But the
far majority of them are probably correct.
quoted
Or faith in that he knows what "unlikely" means.
I should write docs about this; but unlikely() means:
1) It happens less than 0.01% of the cases.
2) The compiler couldn't have figured this out by itself
(NULL pointer checks are compiler done already, same for some other
conditions) 3) It's a hot codepath where shaving 0.5 cycles (less even on
x86) matters (and the author is ok with taking a 500 cycles hit if he's
wrong)
One more thing unlikely() does is to move the unlikely code out of line.
So it should conserve some icache in critical functions, which might
well be worth some more cycles (don't have numbers though).
I actually once measured context switching performance in the scheduler,
and removing the unlikely hint for testing RT tasks IIRC gave about 5%
performance drop.
OT: what benchmarks did you use for that? I had a change some time
ago to the CFS scheduler to avoid unpredicted indirect calls for
the common case, but I wasn't able to benchmark a difference with the usual
suspect benchmark (lmbench). Since it increased code size by
a few bytes it was rejected then.
This was on a P4 which is very different from more modern CPUs both in
terms of branch performance characteristics,
and icache characteristics.
Hmm, the P4 the trace cache actually should not care about inline
code that is not executed.
However, the P4's branch predictor is pretty good, and it should easily
I think it depends on the generation. Prescott class branch
prediction should be much better than the earlier ones.
Actually one thing I don't like about gcc is that I think it still emits
cmovs for likely/unlikely branches,
That's -Os.
which is silly (the gcc developers
It depends on the CPU. e.g. on K8 and P6 using CMOV if possible
makes sense. P4 doesn't like it though.
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
But only when the explicit hints are different from what the implicit
branch predictors would predict anyways. And if you look at the
heuristics that is not often the case...
Also I really think that mm patch that measured unlikely efficiency
should be dug out and merged to mainline and them regularly rechecked.
-Andi
Sometimes, for performance critical paths, I would like gcc to be dumb and
follow *my* code and not its hard-coded probabilities.
If you really want that, simple: just disable optimization @)
Maybe one thing we would need would be the ability to assign probabilities
to each branch based on what we expect, so that gcc could build a better
tree keeping most frequently used code tight.
Just use profile feedback then for user space. I don't think it's a good
idea for kernel code though because it leads to unreproducible binaries
which would wreck the development model.
Hmm I've just noticed -fno-guess-branch-probability in the man, I never tried
it.
From: Nick Piggin <hidden> Date: 2008-02-19 09:47:18
On Tuesday 19 February 2008 20:25, Andi Kleen wrote:
On Tue, Feb 19, 2008 at 01:33:53PM +1100, Nick Piggin wrote:
quoted
I actually once measured context switching performance in the scheduler,
and removing the unlikely hint for testing RT tasks IIRC gave about 5%
performance drop.
OT: what benchmarks did you use for that? I had a change some time
ago to the CFS scheduler to avoid unpredicted indirect calls for
the common case, but I wasn't able to benchmark a difference with the usual
suspect benchmark (lmbench). Since it increased code size by
a few bytes it was rejected then.
I think it was just a simple context switch benchmark, but not lmbench
(which I found to be a bit too variable). But it was a long time ago...
quoted
This was on a P4 which is very different from more modern CPUs both in
terms of branch performance characteristics,
and icache characteristics.
Hmm, the P4 the trace cache actually should not care about inline
code that is not executed.
Yeah, which is why it is a bit different than other CPUs. Although
the L2 cache I guess is still going to suffer from sparse code, but
I guess that is a bit less important.
quoted
However, the P4's branch predictor is pretty good, and it should easily
I think it depends on the generation. Prescott class branch
prediction should be much better than the earlier ones.
I was using a Nocona Xeon, which I think is a Prescott class? And
don't they have much higher mispredict penalty (than older P4s)?
quoted
Actually one thing I don't like about gcc is that I think it still emits
cmovs for likely/unlikely branches,
That's -Os.
And -O2 and -O3, on the gccs that I'm using, AFAIKS.
quoted
which is silly (the gcc developers
It depends on the CPU. e.g. on K8 and P6 using CMOV if possible
makes sense. P4 doesn't like it though.
If the branch is completely predictable (eg. annotated), then I
think branches should be used anyway. Even on well predicted
branches, cmov is similar speed on microbenchmarks, but it will
increase data hazards I think, so it will probably be worse for
some real world situations.
quoted
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
But only when the explicit hints are different from what the implicit
branch predictors would predict anyways. And if you look at the
heuristics that is not often the case...
But a likely branch will be _strongly_ predicted to be taken,
wheras a lot of the gcc heuristics simply have slightly more or
slightly less probability. So it's not just a question of which
way is more likely, but also _how_ likely it is to go that way.
On Tue, Feb 19, 2008 at 08:46:46PM +1100, Nick Piggin wrote:
On Tuesday 19 February 2008 20:25, Andi Kleen wrote:
quoted
On Tue, Feb 19, 2008 at 01:33:53PM +1100, Nick Piggin wrote:
quoted
quoted
I actually once measured context switching performance in the scheduler,
and removing the unlikely hint for testing RT tasks IIRC gave about 5%
performance drop.
OT: what benchmarks did you use for that? I had a change some time
ago to the CFS scheduler to avoid unpredicted indirect calls for
the common case, but I wasn't able to benchmark a difference with the usual
suspect benchmark (lmbench). Since it increased code size by
a few bytes it was rejected then.
I think it was just a simple context switch benchmark, but not lmbench
(which I found to be a bit too variable). But it was a long time ago...
Do you still have it?
I thought about writing my own but ended up being too lazy for that @)
quoted
quoted
However, the P4's branch predictor is pretty good, and it should easily
I think it depends on the generation. Prescott class branch
prediction should be much better than the earlier ones.
I was using a Nocona Xeon, which I think is a Prescott class?
Yes.
And don't they have much higher mispredict penalty (than older P4s)?
They do have a longer pipeline, so yes more penalty (5 or 6 stages more iirc),
but also a lot better branch predictor which makes up for that.
quoted
quoted
Actually one thing I don't like about gcc is that I think it still emits
cmovs for likely/unlikely branches,
That's -Os.
And -O2 and -O3, on the gccs that I'm using, AFAIKS.
Well if it still happens on gcc 4.2 with P4 tuning you should
perhaps open a gcc PR. They tend to ignore these bugs mostly in
my experience, but sometimes they act on them.
quoted
quoted
which is silly (the gcc developers
It depends on the CPU. e.g. on K8 and P6 using CMOV if possible
makes sense. P4 doesn't like it though.
If the branch is completely predictable (eg. annotated), then I
think branches should be used anyway. Even on well predicted
branches, cmov is similar speed on microbenchmarks, but it will
increase data hazards I think, so it will probably be worse for
some real world situations.
At least the respective optimization manuals say they should be used.
I presume they only made this recommendation after some extensive
benchmarking.
quoted
quoted
the quite good numbers that cold CPU predictors can attain. However
for really performance critical code (or really "never" executed
code), then I think it is OK to have the hints and not have to rely
on gcc heuristics.
But only when the explicit hints are different from what the implicit
branch predictors would predict anyways. And if you look at the
heuristics that is not often the case...
But a likely branch will be _strongly_ predicted to be taken,
wheras a lot of the gcc heuristics simply have slightly more or
slightly less probability. So it's not just a question of which
way is more likely, but also _how_ likely it is to go that way.
Yes, but a lot of the heuristics are pretty strong (>80%) and gcc will
act on them unless it has a very strong contra cue. And that should
normally not be the case.
-Andi
From: Nick Piggin <hidden> Date: 2008-02-19 22:25:35
On Tuesday 19 February 2008 20:57, Andi Kleen wrote:
On Tue, Feb 19, 2008 at 08:46:46PM +1100, Nick Piggin wrote:
quoted
I think it was just a simple context switch benchmark, but not lmbench
(which I found to be a bit too variable). But it was a long time ago...
Do you still have it?
I thought about writing my own but ended up being too lazy for that @)
Had a quick look but couldn't find it. It was just two threads running
and switching to each other with a couple of mutexes or yield. If I
find it, then I'll send it over.
quoted
quoted
quoted
Actually one thing I don't like about gcc is that I think it still
emits cmovs for likely/unlikely branches,
That's -Os.
And -O2 and -O3, on the gccs that I'm using, AFAIKS.
Well if it still happens on gcc 4.2 with P4 tuning you should
perhaps open a gcc PR. They tend to ignore these bugs mostly in
my experience, but sometimes they act on them.
I'm not sure about P4 tuning... But even IMO it should not on
predictable branches too much for any (especially OOOE) CPU.
quoted
quoted
quoted
which is silly (the gcc developers
It depends on the CPU. e.g. on K8 and P6 using CMOV if possible
makes sense. P4 doesn't like it though.
If the branch is completely predictable (eg. annotated), then I
think branches should be used anyway. Even on well predicted
branches, cmov is similar speed on microbenchmarks, but it will
increase data hazards I think, so it will probably be worse for
some real world situations.
At least the respective optimization manuals say they should be used.
I presume they only made this recommendation after some extensive
benchmarking.
What I have seen is that they tell you definitely not to use it for
predictable branches. Eg. the Intel optimization manual says
Use the setcc and cmov instructions to eliminate unpredictable
conditional branches where possible. Do not do this for predictable
branches. Do not use these instructions to eliminate all
unpredictable conditional branches, because using these instructions
will incur execution overhead due to executing both paths of a
conditional branch. In addition, converting conditional branches to
cmovs or setcc trades control-flow dependence for data dependence
and restricts the capability of the out-of-order engine.
quoted
But a likely branch will be _strongly_ predicted to be taken,
wheras a lot of the gcc heuristics simply have slightly more or
slightly less probability. So it's not just a question of which
way is more likely, but also _how_ likely it is to go that way.
Yes, but a lot of the heuristics are pretty strong (>80%) and gcc will
act on them unless it has a very strong contra cue. And that should
normally not be the case.
True, but if you know a branch is 99%+, then use of likely/unlikely
can still be a good idea. 80% may not be enough to choose a branch
over a cmov for example.
On Tue, Feb 19, 2008 at 10:28:46AM +0100, Andi Kleen wrote:
quoted
Sometimes, for performance critical paths, I would like gcc to be dumb and
follow *my* code and not its hard-coded probabilities.
If you really want that, simple: just disable optimization @)
already tried. It fixed some difficulties, but create new expected issues
with data being reloaded often from memory instead of being passed along
a few registers. Don't forget that optimizing for x86 requires a lot of
smartness from the compiler because of the very small number of registers!
quoted
Maybe one thing we would need would be the ability to assign probabilities
to each branch based on what we expect, so that gcc could build a better
tree keeping most frequently used code tight.
Just use profile feedback then for user space. I don't think it's a good
idea for kernel code though because it leads to unreproducible binaries
which would wreck the development model.
I never found this to be practically usable in fact, because you have to
use it on the *exact* same source. End of game for cross-compilation. It
would be good to be able to use a few pragmas in the code to say "hey, I
want this block optimized like this". This is what I understood the
__builtin_expect() was for, except that it tends to throw unpredicted
branches too far away.
quoted
Hmm I've just noticed -fno-guess-branch-probability in the man, I never tried
it.