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)BlockLayoutMinDiamondPercentage/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, BlockLayoutMinDiamondPercentage is default 20 so infrequent_prob become 0.2 as you observed.

Yes, there's a sharp edge somewhere below 0.2.

">

(original) (raw)

Hi Vladimir!

On Sat, Feb 8, 2014 at 4:36 AM, Vladimir Kozlov <vladimir.kozlov@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)BlockLayoutMinDiamondPercentage/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, BlockLayoutMinDiamondPercentage 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
but this is nearly always less efficient than using CMOVcc.

Regards,
Martin.