Goo optimization optimizer

I have a "MyFunction" which I continue to obsess if I should or should not use goto on it and in similar (hopefully rare) circumstances. Therefore, I am trying to establish a tough habit for this situation. To do or not to do.

int MyFunction() { if (likely_condition) { condition_met: // ... return result; } else /*unlikely failure*/ { // meet condition goto condition_met; } } 

I was about to take advantage of the failed conditional branch command for the likely case. However, I don’t see how the compiler could know that to optimize the probability of a case without this.

  • Does it work correctly?
  • - benefits worth confusing.
  • Are there any better (less detailed, more structured, more expressive) ways to enable this optimization?
+4
source share
4 answers

A modern processor will accept this branch anyway with equal performance if it makes the correct branch prediction. So, if it's in the inner loop, performance if (unlikely) { meet condition } common code; will match what you wrote.

In addition, if you specify common code in both branches, the compiler will generate code identical to what you wrote: the general case will be emitted for the if clause, and the else clause will be jmp to the common code. You see this all the time in simpler terms such as *out = whatever; return result; *out = whatever; return result; . When debugging, it can be difficult to determine which return you are looking at, because they have all been merged.

+4
source

It seems to me that the optimization you are trying to do is basically out of date. Most modern processors have built-in branch prediction, so (provided that it is used enough to notice), they track how often a branch is accepted or not, and predict whether the branch can be accepted or not based on its past picture, which you need to accept or not, in this case, the speed depends primarily on how accurate this prediction is, and whether the prediction is accepted or not.

So you are probably best using simpler code:

 int MyFunction() { if (!likely_condition) { meet_condition(); } // ... return result; } 
+5
source
  • It looks like the code should work as you expect until condition_met: misses the variable initialization.

  • No, and you don’t even know that the confusing version compiles into more optimal code. Compiler optimization (and prediction of processor branching) has recently become very smart.

3.

 int MyFunction() { if (!likely_condition) { // meet condition } condition_met: // ... return result; } 

or if this helps your compiler (check the build)

 int MyFunction() { if (likely_condition); else { // meet condition } condition_met: // ... return result; } 
+4
source

I would highly recommend using the __builtin_expect() (GCC) macro or similar for your specific C ++ compiler (see tips for predicting portable branches ) instead of using goto

 int MyFunction() { if (__builtin_expect(likely_condition)) { // ... return result; } else /*unlikely failure*/ { // meet condition } } 

As others have noted, goto is a tendency to make mistakes and evil from bones.

+1
source

Source: https://habr.com/ru/post/1443294/


All Articles