I have the following test in MinGW in my winx , compiled by :
g++ -std=c++11 -DTEST2 testatomic1.cpp -lpthread -o testatomic1.exe
g++ -std=c++11 -DTEST4 testatomic1.cpp -lpthread -o testatomic1.exe
atomic_int totalx(0);
void *test_func0(void *arg)
{
#ifdef TEST2
for(i=0;i<100000000;++i){
totalx += 1 ;
}//for
#endif
#ifdef TEST4
for(i=0;i<100000000;++i){
atomic_fetch_add(&totalx, 1);
}//for
#endif
}
int main(int argc, const char *argv[])
{
pthread_t id[3];
int iCPU =1 ;
pthread_create(&id[0],NULL,test_func0,(void *)(long)iCPU );
pthread_create(&id[1],NULL,test_func0,(void *)(long)iCPU );
pthread_create(&id[2],NULL,test_func0,(void *)(long)iCPU );
int i ;
for(i=0;i<3;++i){
pthread_join(id[i],NULL);
}
#ifdef TEST2
cout << "TEST2 totalx=" << totalx << endl ;
#endif
#ifdef TEST4
cout << "TEST4 totalx=" << totalx << endl ;
#endif
}//main
This test run many times in TEST2 and TEST4 defined , and answer are 300000000 all , in TEST4 , it works as I expect , TEST2 is strange to me , totalx += 1 ; without any memory model , can produce the right answer ...then why bother has load , store function ? just define an atomic_int var will do the job right , I wonder it is too easy ... Am I miss something ?
The C++11 standard defines atomic_XXX
as a typedef
of std::atomic<XXX>
([atomics.types.generic] p7). std::atomic<int>
has an operator+=(int)
that is defined to have the same effects as atomic_fetch_add
([atomics.types.operations.pointer] p27). So your two test sequences are defined to have identical effects.
The atomic_XXX
types are for C11 compatibility - you may have an easier time simply using std::atomic<XXX>
.