On Mon, Jan 22, 2018 at 01:52:11PM +0100, Jan Hubicka wrote: > In new code bb4 is reached by first_prob + (1-first_prob)*second_prob > which should be equal to prob. > > Say your choosen constant is to obtain first_prob=c*prob is c=0.99 and you > want to know c2 to obtain second_prob=c2*prob > > You want the combined probability of branch (c*prob)+(1-c*prob)*(prob*c2) to > be the same prob > > This should give c2=(1-c)/(1-c*prob) so > (c*prob)+(1-c*prob)*prob*(1-c)/(1-c*prob) cancels out to c*prob+(1-c)*prob > > that is > profile_probability cprob = > profile_probability::guessed_always ().apply_scale (1, 100); > first_prob = prob * cprob;
Yes, if we want it to be done with arbitrary cprob, we can do it the above way and move the latter into the helper. > prob = cprob.inverse () / (first_prob).inverse (); But this looks incorrect, because that computes only the above c2 in prob, not second_prob. It needs to be prob = cprob.invert () * prob / first_prob.invert (); or prob *= cprob.invert () / first_prob.invert (); or that prob = (prob - first_prob) / first_prob.invert (); I had in the patch. The last one looked to me like cheapest to compute. > void profile_probability::split (profile_probability cprob, > profile_probability *first_prob, profile_probability *second_prob) This doesn't take prob as an argument, or should it be a method and take prob as *this? Couldn't it simply return first_prob and adjust itself, so profile_probability split (profile_probability cprob) { profile_probability ret = *this * cprob; *this = (*this - prob) / ret.invert (); // or *this = *this * cprob.invert () / ret.invert (); return ret; } ? > > I would bet we already have something like that but don't see it. > > Other cases seems to choose c as 1/2 that simplifies the formulate bit it > is also easy to get misunderstand such as in: > profile_probability false_prob = prob.invert (); > profile_probability op0_false_prob = false_prob.apply_scale (1, > 2); > profile_probability op1_false_prob = false_prob.apply_scale (1, > 2) > / op0_false_prob.invert (); Or profile_probability op1_false_prob = op0_false_prob / op0_false_prob.invert (); Jakub