New GCC takes 19x as long to compile my program (compared to old GCC), plus void** patch suggestion
Elmar Krieger
elmar@cmbi.ru.nl
Wed Aug 8 19:07:00 GMT 2012
Hi David, hi Andrew,
>> One other thing I just thought of: GCC has a history of very smart
>> extensions to C that allow to write faster and more elegant code. If I
>> look at my code, there are mostly two sources of 'dirty hacks' left. One
>> that could be fixed easily is the 'void** pointer problem', that
>> clutters my code with nasty explicit type casts:
>>
>> A simple example is the function freesetnull, that frees a pointer and
>> sets it NULL (ptradd is a pointer address):
>>
>> void freesetnull(void **ptradd)
>> { free(*ptradd);
>> *ptradd=NULL; }
>>
>
> Normally, good style encourages using static inline functions instead of
> macros, but here I would go for a macro:
>
> freesetnull(_p) do { free(_p); _p = NULL; } while (0)
>
> Note the slight change in the semantics - you pass the pointer, not a
> pointer to the pointer.
>
> I expect this will also have the bonus of improving the speed of the
> resulting program - and possibly even of the compilation.
Many thanks, but this was really just the most simple example to
illustrate how GCC's prohibition to pass a 'pointer to any pointer' to a
function expecting a void** causes more problems than it solves. In your
case, you are forced to use a macro (with the usual side-effects
problem) instead of a safe 'static inline' to circumvent the problem.
But my code is full of cases that go beyond what can reasonably be done
with macros.
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'.
> Regarding compile time, modern gcc has "-funit-at-a-time" and
> "-ftop-level-reorder" enabled by default, even with no optimisation
> enabled. These could take time on such a huge source code. Try compiling
> with "-fno-unit-at-a-time" (which implies "-fno-toplevel-reorder").
Many thanks, tried that and the time at -O !increased! (I am writing
this from a slower computer) from 6 minutes 38 to 7 minutes. BTW, the
time with -O0 is just 17 seconds.
And to Andrew Haley:
>> To me, that just looks like a remnant from the ancient past that hinders
>> the future. On the other hand, my feeling tells me that this patch would
>> not be accepted, that's why I'm asking for my chances in advance ;-)
>
> 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?
All the best,
Elmar
--
Elmar Krieger, PhD
YASARA Biosciences & CMBI Outstation Austria
Wagramer Strasse 25/3/45
1220 Vienna
Austria/Europe
www.YASARA.org
More information about the Gcc
mailing list