[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