c++ - GCC 4.7.2 on Debian amd64 - built-in atomic increment? -


my test source is:

volatile int gl = 0;  void * internalhandler( void * param ) {   ( int = 0; < 100000; ++i ) { ++gl; }   return 0; }  int main() {   pthread_t ths[100] = { 0 };   ( int = 0; < 100; ++i)   {     pthread_create( &ths[ ], 0, internalhandler, 0 );   }   ( int = 0; < 100; ++i)   {     pthread_join( ths[ ], 0 );   }   std::cout << gl << std::endl;   return 0; } 

when compile , run code on debian (via virtualbox), 10000000 every time, while has race condition.

uname -a:

linux debian-dev 3.2.0-4-amd64 #1 smp debian 3.2.46-1 x86_64 gnu/linux 

gcc -v:

using built-in specs. collect_gcc=gcc collect_lto_wrapper=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper target: x86_64-linux-gnu configured with: ../src/configure -v --with-pkgversion='debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/readme.bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu thread model: posix gcc version 4.7.2 (debian 4.7.2-5) 

on several other systems different results. race conditions job. on virtual debian it's "implicit atomic". why be?

there data race.

you don't see because virtual machine using single core; , running on architecture performs increment using single cpu instruction (meaning task switch can't happen in middle of it).

if run on multi-core machine, or architecture (such arm) doesn't have cpu instructions directly modifying values in memory, should see inconsistent results expected.

for example, if run on 8-core machine get:

$ ./a.out  1666121 $ ./a.out  1632606 

while constraining single core gives

$ taskset -c 0 ./a.out  10000000 $ taskset -c 0 ./a.out 10000000 

you can fix data race using std::atomic<int>. if c++11 not available, use platform-specific atomic operations such gcc's __sync_fetch_and_add, or (if performance impact acceptable) guard variable mutex.


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -