[cairo] fixed_from_double speedup masking pixman traps problem

Bill Spitzak spitzak at d2.com
Wed Nov 29 17:26:54 PST 2006



Behdad Esfahbod wrote:
> On Wed, 2006-11-29 at 15:48 -0500, Bill Spitzak wrote:
>> In the fast fixed-from-double code, overflow can be detected because
>> the 
>> "high word" of the resulting double after the math must be a
>> constant. 
>> If it is not the expected value then overflow occurred and you can
>> then 
>> use some slower code to do the conversion.
>>
>> I tried this here but the overhead of the if statement killed most of 
>> the speed advantage, also investigation of our code indicated that at 
>> least 90% or so of all calls to our float->int converter was from
>> code 
>> that already knew the number was in range. So I did not do this.
>> However 
>> it does appear to be the fastest way to make a flawless converter.
>>
> 
> So, then adding a variant that returns a overflowed boolean and let the
> caller deal with an overflow?

I suspect that is the best idea. There should be a completely different 
function that does the conversion and test at the same time. The version 
I wrote returned false on failure and took the address of the output, 
something like this:

int fixed;
if (!fixed_from_double_checked(&fixed,x)) {
   fixed = int(x*65536); // or whatever is needed to get correct number
}

However there needs to be some tests to see if this is actually faster. 
It may be that the following code is faster:

if (x < MINIMUM_DOUBLE_THAT_WORKS) {
   fixed = int(x*65536);
} else if (x <= MAXIMUM_DOUBLE_THAT_WORKS) {
   fixed = fixed_from_double(x);
} else {
   fixed = int(x*65536);
}

If the above is faster or about the same then the other function should 
not be added.

It may also be that the useful range intersects only part of the range 
the conversion works, in particular when 0 is one end of the range. It 
may be that this code:

if (x <= 0) {
   fixed = 0;
} else if (x <= MAXIMUM_DOUBLE_THAT_WORKS) {
   fixed = fixed_from_double(x);
} else {
   fixed = int(x*65536);
}

is faster than:

if (x <= 0) {
   fixed = 0;
} else if (!fixed_from_double_checked(&fixed,x)) {
   fixed = int(x*65536);
}

It would be possible to make yet another converter & test function that 
adds a different constant so that negative numbers fail.



More information about the cairo mailing list