Unexpected optimizer behavior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux