Unexpected optimizer behavior
Frank Neuhaus
dtag00@gmail.com
Fri Jun 26 18:04:00 GMT 2009
Hi,
I am looking at a case where the gcc's optimizer shows some
'unexpected' behavior:
Please look at this code:
#include <stdio.h>
struct Image
{
Image()
{
w=h=0;
pixels=0;
}
~Image()
{
delete[] pixels;
}
void resize(int width, int height);
int w;
int h;
unsigned char* pixels;
};
/* inline */ void Image::resize(int width, int height) // HERE
{
pixels=new unsigned char[width*height];
w=width;
h=height;
};
int main()
{
Image img;
img.resize(400,300);
for (int i=0;i<50000;i++)
for (int y=0;y<300;y++)
for (int x=0;x<400;x++)
img.pixels[y*400+x]=17;
printf("Done! %d",img.pixels[50]); // make sure the optimizer does
not throw everything away :)
return 0;
}
I highlighted one line with "HERE":
If I inline the function resize, everything performs as expected.
Specifically the loop in the main function is performed very fast
(takes like 3.8 sec on my machine). However if I do _not_ inline the
function "resize", it seems like it affects the way the loop in the
main function is compiled. The program suddenly runs twice as long. I
looked at the assembly that is being generated and it seems like
img.pixels no longer gets cached in a register, but instead it
retrieves the pixels variable every single loop iteration from the img
struct.
I am compiling with g++ -O2. The problem does not appear to show up
with -O3 (at least I was not able to reproduce it). The question is:
Why does the optimizer show the above behavior? Why does inlining (or
not) a marginally related function affect this loop which basically
has nothing to do with "resize"?
Thank you very much
Frank
Oh and I am using Fedora 11 with the following gcc -v output:
Using built-in specs.
Target: i586-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap
--enable-shared --enable-threads=posix --enable-checking=release
--with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic
--with-arch=i586 --build=i586-redhat-linux
Thread model: posix
gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC)
More information about the Gcc-help
mailing list