Strange branching performance
Vladimir Kozlov
vladimir.kozlov at oracle.com
Wed Feb 12 18:33:42 PST 2014
We can try to use hint prefixes for branches as experiment:
http://software.intel.com/en-us/articles/branch-and-loop-reorganization-to-prevent-mispredicts
Thanks,
Vladimir
On 2/12/14 6:14 PM, Vitaly Davidovich wrote:
> FWIW, I recall reading on gcc forums that someone made a comparison of
> cmov vs jmp on i7 and bulldozer, and concluded that cmov becomes better
> if the branch is predicted < 92% of the time or so. In addition,
> bulldozer suffered bigger penalty for cmov than intel. I can try to dig
> up that thread if there's interest.
>
> In addition to register pressure, cmov also adds a dependency chain and
> the instruction size is bigger.
>
> I guess try to write code with more predictable branching is the answer :).
>
> Sent from my phone
>
> On Feb 12, 2014 7:20 PM, "Vladimir Kozlov" <vladimir.kozlov at oracle.com
> <mailto:vladimir.kozlov at oracle.com>> wrote:
>
> Hi Martin,
>
> The issue is more complicated than I thought. The code I pointed
> before was added by me about 3 years ago for:
>
> 7097546: Optimize use of CMOVE instructions
> https://bugs.openjdk.java.net/__browse/JDK-7097546
> <https://bugs.openjdk.java.net/browse/JDK-7097546>
>
> Changes were done to avoid 2x performance hit with cmov for code
> like next:
>
> public static int test(int result, int limit, int mask) { //
> mask = 15
> for (int i = 0; i < limit; i++) {
> if ((i&mask) == 0) result++; // Non frequent
> }
> return result;
> }
>
> Cmov instruction has big flow - it requires an additional register.
> If loop's body is complex, using cmov will result in a register
> spilling - additional instructions. The performance hit could be
> high than branch misprediction.
>
> I am not sure how to proceed from here. I may do some benchmark
> testing to see affects if cmov is used in more cases.
>
> Regards,
> Vladimir
>
> On 2/8/14 1:11 PM, Martin Grajcar wrote:
>
> Hi Vladimir!
>
> On Sat, Feb 8, 2014 at 4:36 AM, Vladimir Kozlov
> <vladimir.kozlov at oracle.com <mailto:vladimir.kozlov at oracle.com>
> <mailto:vladimir.kozlov at __oracle.com
> <mailto:vladimir.kozlov at oracle.com>>> wrote:
>
> Hi Martin,
>
> Your observation is correct. The corresponding code is next:
>
> float infrequent_prob = PROB_UNLIKELY_MAG(3); // 0.001
>
> // BlockLayoutByFrequency optimization moves infrequent
> branch
> // from hot path. No point in CMOV'ing in such case (110
> is used
> // instead of 100 to take into account not exactness of
> float value).
> if (BlockLayoutByFrequency) {
> infrequent_prob = MAX2(infrequent_prob,
> (float)____BlockLayoutMinDiamondPercentag____e/110.0f);
> }
> // Check for highly predictable branch. No point in
> CMOV'ing if
> // we are going to predict accurately all the time.
> if (iff->_prob < infrequent_prob ||
> iff->_prob > (1.0f - infrequent_prob))
> return NULL;
>
> Note, BlockLayoutMinDiamondPercentag____e is default 20 so
> infrequent_prob become 0.2 as you observed.
>
>
> Yes, there's a sharp edge somewhere below 0.2.
>
> C2 moves infrequent code outside the loop (with branches
> out and
> back) to keep only hot code inside.
>
>
> To me it looks like there's nothing to be moved outside of the loop.
> Mainly because you'd hardy save anything as you'd replace the two
> instructions
>
> LEA (%result_reg, 1), %tmp_reg
> CMOVEQ %tmp_reg, %result_reg
>
> by a conditional jump. Saving a single instruction on the hot
> path and
> risking a branch misprediction penalty might make sense for very low
> probabilities like PROB_UNLIKELY_MAG(3), not 20%.
>
> It looks like it does not happen in your case and I need to
> look
> why. There are several conditions besides
> BlockLayoutByFrequency and
> the above code could be incorrect and needs to be fixed (or
> removed).
>
>
> Nice that you can look into it. There are a lot of attempts to
> eliminate
> branching manually like in
> http://grepcode.com/file/__repo1.maven.org/maven2/com.__google.guava/guava/15.0/com/__google/common/math/IntMath.__java#IntMath.gcd%28int%2Cint%__29
> <http://grepcode.com/file/repo1.maven.org/maven2/com.google.guava/guava/15.0/com/google/common/math/IntMath.java#IntMath.gcd%28int%2Cint%29>
> but this is nearly always less efficient than using CMOVcc.
>
> Regards,
> Martin.
>
More information about the hotspot-compiler-dev
mailing list