On Fri, Aug 10, 2012 at 5:44 PM, Elmar Krieger <el...@cmbi.ru.nl> 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 1844272maxresident)k 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 427392maxresident)k 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 1752784maxresident)k 0inputs+0outputs (0major+124029minor)pagefaults 0swaps same time, I am surprised again ;) (with improvements in CPU speed the compilation 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. Richard. > To Ian: > > >>>> Not at all high. See Type-Based Alias Analysis >>>> <http://www.drdobbs.com/cpp/type-based-alias-analysis/184404273> >>>> 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'. >> > >