[cairo-bugs] [Bug 4846] Performance problems for GTK+/Cairo on MacOS X

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Wed Oct 26 16:03:07 PDT 2005


Please do not reply to this email: if you want to comment on the bug, go to    
       
the URL shown below and enter yourcomments there.     
   
https://bugs.freedesktop.org/show_bug.cgi?id=4846          
     




------- Additional Comments From bogdanni at hotmail.com  2005-10-26 16:03 -------
For the record, it was a bug in the compiler, although I still cannot explain how I got those huge 
numbers... I made a test case and reported it to Apple.

Now for the topic of rounding. I would say first you should define exactly your definition of rounding 
which is appropriate for your problem domain. It should be specified unambiguously.

For example, according to the definition of the round() function, half-way numbers are rounded away 
from zero (this is the intention of the code in comment #13, but doesn't work for all input, see 
comment #14).

An alternate specification which is statistically unbiased: half-way numbers are rounded to the closest 
even integer. This is what CPUs usually implement, what rint() does when the rounding mode is 
FE_TONEAREST (this function is inappropriate for a library, because the application can change the 
rounding mode) and what Mathematica does (see http://mathworld.wolfram.com/
NearestIntegerFunction.html).

I read before the conversation you linked to :-). I had for long time a variant of that code, see below, 
which I think is more resilient to breaking when the compiler becomes more and more aggressive in its 
optimizations. Also, for Pentium4, I think it's not that faster anymore, you may need to run some tests 
with -march=pentium4 flag for gcc.

Unfortunately those kind of definitions don't work for certain values. And it's worrying that they fail 
around +- 0.5 which I think are interesting values for Cairo. You can test with the program below (you 
may need to compile with -std=c99 for gcc).

predecessor of 0.5 = + (.5 - 0x1p-54)
successor of -0.5   = - (.5 - 0x1p-54)

The code in comment #13 fails for both, current Cairo for the predecessor of 0.5 and the other trick for 
the successor of -0.5.

The round() function, while technically required by C99, it was implemented for long time in Linux, 
BSDs, other Unices and even Windows. I think it is much better tested and has a crystal clear definition.
It may happen that gcc in the future will replace it with inline code (hopefully not buggy like it 
happened to me).

Cairo is already critical infrastructure, please make it fail-proof and idiot-proof (that's me :-))
With my unfortunate experience that started this thread, I would be cautious.

And, btw, thank you Carl et al for this brilliant piece of software.

#include <math.h>
#include <stdio.h>

/* big endian
#define iman 1
*/

/* little endian */
#define iman 0

int round1(const double val)
{
static union { double d; int i[2]; } u;                                                                                                       
    u.d = val + 68719476736. * 1.5;                                                                                                           
    return (u.i[iman]) >> 16;
}

int round2(const double val)
{
	if (val < 0.)
		return (int) (val - .5);
	else
		return (int) (val + .5);
}

int round3(const double val)
{
	return (int) floor(val + .5);
}

int main(void)
{
     double p = + (.5 - 0x1p-54);
     double m = - (.5 - 0x1p-54);

     printf("%d %d\n", round1(p), (int) round(p));
     printf("%d %d\n", round1(m), (int) round(m));

     return 0;
}
          
     
     
--           
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email         
     
------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.


More information about the cairo-bugs mailing list