Thanks for the quick response. I looked at the assembly code, and found it a bit strange. Here are the two while loops in comparison: while ( g_counter == 0 ); -O0 0x08048567 <main+102>: mov 0x80497f8,%eax 0x0804856c <main+107>: test %eax,%eax 0x0804856e <main+109>: je 0x8048567 <main+102> -O1 0x0804853a <main+102>: mov 0x80497f8,%eax 0x0804853f <main+107>: test %eax,%eax 0x08048541 <main+109>: je 0x8048541 <main+109> <--- jumping to itself, so only testing the first time through So, the -O0 is doing what I would expect, but the -O1 version IS testing the global variable the first pass, but then never jumping back to the 0x0804853a to retrieve the new global value and then re-test. Is this right? -Tynan On Thu, Feb 14, 2008 at 10:17 AM, Tony Wetmore <tony.wetmore@xxxxxxxxxxxx> wrote: > Tynan, > > I think the difference is that when GCC optimizes the code, it > eliminates the g_counter variable entirely, since it "never changes" > within the body of the loop, so the loop becomes "while(false) ;". > > When you add the "volatile" qualifier, you are instructing GCC not to > optimize the variable away, since its value may change in ways that are > unpredictable by GCC. > > If you look at the assembly code generated in the -O0 and -O1 cases, the > difference should be very obvious in this simple test case. > > -- > Tony Wetmore > > > > > Tynan Wilke wrote: > > Hello list, > > > > If I am posting in the wrong place, I apologize. I was making some > > test scripts this morning and found a pretty glaring difference > > between my optimized (-O1) versus my unoptimized (-O0) test code. > > Below, is the a quick example that I made showing the problem: > > -------------------------------- > > #include <pthread.h> > > #include <stdio.h> > > #include <stdlib.h> > > > > static int g_counter = 0; > > > > void *IncThread(void* nothing) > > { > > printf("Thread started\n"); > > while( 1 ) > > { > > g_counter++; > > // printf("thread g_counter: %d\n", g_counter ); > > } > > return NULL; > > } > > > > int main() > > { > > pthread_t thread; > > if ( 0 != pthread_create(&thread, NULL, IncThread, NULL ) ) > > { > > perror("Failed to create thread"); > > exit(1); > > } > > > > printf("Waiting for counter...\n"); > > while ( g_counter == 0 ); > > > > while ( g_counter < 1000000 ) > > printf("g_counter: %d\n", g_counter); > > > > printf("Done!\n"); > > return 0; > > } > > -------------------------------- > > > > And compile as follows: > > $ gcc -O0 -lpthread main.c -o out > > > > When run, gives the expected output: > > $ ./out > > Waiting for counter... > > Thread started > > g_counter: 734 > > g_counter: 9198 > > g_counter: 10334 > > g_counter: 11109 > > ... snip ... > > g_counter: 986568 > > g_counter: 987310 > > Done! > > > > If I compile with -O1, the issue arrises: > > $ gcc -O1 -lpthread main.c -o out > > $ ./out > > Waiting for counter... > > Thread started > > > > And nothing else is printed out since it is stuck on the first while > > loop because g_counter is remains 0 in the main thread (but it is > > getting incremented in IncThread). I get the same results if g_counter > > is not static. The code works fine if I make g_counter volatile. > > > > Here is the gcc version I'm using, which is straight from the RH repo: > > $ gcc -v > > Using built-in specs. > > Target: i386-redhat-linux > > Configured with: ../configure --prefix=/usr --mandir=/usr/share/man > > --infodir=/usr/share/info --enable-shared --enable-threads=posix > > --enable-checking=release --with-system-zlib --enable-__cxa_atexit > > --disable-libunwind-exceptions --enable-libgcj-multifile > > --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.4.2-gcj-1.4.2.0/jre > > --with-cpu=generic --host=i386-redhat-linux > > Thread model: posix > > gcc version 4.1.2 20070626 (Red Hat 4.1.2-14) > > > > Also, I'm on a quad-core Xeon, if that makes a difference. > > > > I have to imagine that this is due to some bad assumptions on my end, > > but I would really like to know why optimising this relatively > > straightforward code causes it to behave differently. Any help is > > greatly appreciated. > > > > Thanks, > > Tynan > > > > > >