This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: New GCC takes 19x as long to compile my program (compared to old GCC), plus void** patch suggestion

On Fri, Aug 10, 2012 at 5:44 PM, Elmar Krieger <> wrote:
> Hi Ian, hi Richard, hi Andi!
> Many thanks for your comments.
>>>> The slowdown is not the same with other files, so I'm essentially sure
>>>> that this specific source file has some 'feature' that catches GCC at
>>>> the wrong leg. This raises my hopes that one of the GCC experts wants
>>>> to take a look at it. The code is confidential,
>>> You could file a bug report with just a profile output of the compiler
>>> (e.g. from oprofile or perf)
>> But please use a pristine FSF compiler.  You can also run the source
>> through
>> some obfuscation tool.  Or get a first hint with using -ftime-report.
>> In the end, without a testcase there is nothing to do for us ...
> I downloaded the latest official GCC 4.7.1, but unfortunately configure
> stopped with "Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+.",
> and for my CentOS Linux, only older versions of this libs are available as
> RPMs. I saw many hours of manual fiddling ahead, so I suggest a more
> efficient solution:
> I now sent the confidential source file by private message to Richard,
> please spend 5 minutes to run these two commands with it:
> time gcc -m32 -g -O0 -fno-strict-aliasing -x c -Wall -Werror -c model.i

/usr/bin/time /space/rguenther/install/gcc-3.2.3/bin/gcc -S -o
/dev/null model.i -march=i386 -fno-strict-aliasing -g -w
3.30user 0.03system 0:03.34elapsed 99%CPU (0avgtext+0avgdata 277072maxresident)k
0inputs+0outputs (0major+20416minor)pagefaults 0swaps

/usr/bin/time gcc-4.6 -S -o /dev/null model.i -march=i386
-fno-strict-aliasing -g -m32 -w
3.28user 0.08system 0:03.38elapsed 99%CPU (0avgtext+0avgdata 985760maxresident)k
0inputs+0outputs (0major+64353minor)pagefaults 0swaps

Same time.  I am positively surprised.

> time gcc -m32 -g -O -fno-strict-aliasing -x c -Wall -Werror -c model.i

/usr/bin/time /space/rguenther/install/gcc-3.2.3/bin/gcc -S -o
/dev/null model.i -march=i386 -fno-strict-aliasing -g -w -O
8.09user 0.13system 0:08.29elapsed 99%CPU (0avgtext+0avgdata 381376maxresident)k
248inputs+0outputs (1major+38855minor)pagefaults 0swaps

/usr/bin/time gcc-4.6 -S -o /dev/null model.i -march=i386
-fno-strict-aliasing -g -m32 -w -O
15.33user 0.16system 0:15.55elapsed 99%CPU (0avgtext+0avgdata
24inputs+0outputs (1major+125893minor)pagefaults 0swaps

That's within reasonable bounds as well, IMHO (you can't really compare
-O1 from 3.2.3 with -O1 from 4.6.3).  One more data point (-O2 tends to
be more focused on, no debuginfo generation turns off improvements
and its costs there):

/usr/bin/time /space/rguenther/install/gcc-3.2.3/bin/gcc -S -o
/dev/null model.i -march=i386 -fno-strict-aliasing -w -O2
17.31user 0.43system 0:17.82elapsed 99%CPU (0avgtext+0avgdata
72inputs+0outputs (2major+69895minor)pagefaults 0swaps

/usr/bin/time gcc-4.6 -S -o /dev/null model.i -march=i386
-fno-strict-aliasing  -m32 -w -O2
18.12user 0.21system 0:18.43elapsed 99%CPU (0avgtext+0avgdata
0inputs+0outputs (0major+124029minor)pagefaults 0swaps

same time, I am surprised again ;) (with improvements in CPU speed the
with 4.6.3 is actually _faster_ comparing commodity platforms from the
date of the compiler releases).

> If you don't find an enormous slowdown with the second command (please post
> your timings) and conclude that this problem has been introduced by Google
> in their custom GCC, I'll pay you 100 USD for the 5 minutes wasted.

You might want to try -ftime-report, if it says you have extra checkings enabled
for one compiler but not the other that will explain the different outcome at
your side:

Extra diagnostic checks enabled; compiler may run slowly.
Configure with --enable-checking=release to disable checks.

Disclaimer: I had to delete an include statement on top of the file I sent you
to make it compile.


> To Ian:
>>>> Not at all high.  See Type-Based Alias Analysis
>>>> <>
>>>> for one reason.
>>> Thanks, I read the article, but didn't really see how forbidding a
>>> function
>>> with argument void** to accept a pointer to any pointer helps with
>>> aliasing.
>>> If it's perfectly normal that a function with argument void* accepts any
>>> pointer, then a function with argument void** should accept a pointer to
>>> any
>>> pointer by analogy, without having additional aliasing problems, no?
>> The C and C++ languages could work that way, yes.  But they don't.
>> GCC attempts to implement the standard language.
> Yep, that's why I mentioned how GCC's smart extensions to the standard
> language saved the day many times in the past ;-)
>> Aliasing issues arise when a function has two pointers, and determine
>> whether an assignment to *p1 might change the value at *p2.  There are
>> no aliasing issues with a void* pointer, because if p1 is void* then
>> *p1 is invalid.  That is not true for a void** pointer, so aliasing
>> issues do arise.  If p1 is void** and p2 is int**, then GCC will
>> assume that an assignment to *p1 does not change the value at *p2, as
>> the language standard states.  It's easy to imagine that that could
>> break a program after inlining.
> Many thanks for the clarification, and it also points to a simple solution:
> GCC could simply permit to pass a pointer to any pointer to a function, if
> the function argument is of type 'void **restrict myptr'.
> If adding a 'restrict' to a function declaration was the only thing required
> to get rid of countless nasty explicit type casts, the day would already be
> saved. There really seem to be lots of problem classes that cannot be solved
> with explicit type casts otherwise. The example for loading a binary file
> from disk and allocating the required memory to store the file contents
> being just one of them...
> Best regards,
> Elmar
>> Just one more complicated example:
>> A function that loads a binary file from disk and allocates the required
>> memory to store the file contents, returning the number of bytes read.
>> dstadd is the address where the newly allocated pointer is stored:
>> int dsc_loadfilealloc(void *dstadd,char *filename)
>> { int read,size;
>>   FILE *fb;
>>   if ((fb=fopen(filename,"rb")))
>>   { size=dsc_filesize(filename);
>>     *(void**)dstadd=mem_alloc(size);
>>     read=dsc_readbytes(*(void**)dstadd,fb,size);
>>     *(void**)dstadd=mem_realloc(*(void**)dstadd,read);
>>     fclose(fb);
>>     return(read); }
>>   *(void**)dstadd=NULL;
>>   return(0); }
>> Again, nasty casts all over the place, which would all disappear if GCC
>> allowed me to write
>> int dsc_loadfilealloc(void **dstadd,char *filename)
>> which could then be used to load anything from text files to an array of
>> 'struct foo'.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]