I am trying to learn how to use OpenMP locks, for which I am testing it on a program that generates a histogram, given some data.
I generate some random numbers with the following:
unsigned long seed = 9876543210 ;
std::mt19937_64 gen {seed} ;
float mu = 5.0 ;
float sigma = 1.0 ;
std::normal_distribution<float> dist {mu, sigma} ;
int N = 5000 ;
float array[N] ;
for( int i=0; i<N; ++i ) array[i] = dist( gen ) ; // store random numbers
To generate histogram (within a range [min, max]) with OpenMP locks, I do the following:
int bins = 5 ;
int hist[bins] ;
int ival ;
for( ival=0; ival<bins; ++ival ) hist[ival] = 0 ;
omp_lock_t locks[bins] ;
for( ival=0; ival<bins; ++ival ) omp_init_lock(&locks[ival]) ;
float min = mu - 3*sigma ;
float max = mu + 3*sigma ;
float scale = (max - min) / bins ;
int i ;
#pragma omp parallel for num_threads( 4 )
for( i=0; i<N; ++i ) {
ival = (int) floorf( (array[i] - min) / scale ) ; // bin index
if( ival < 0 || ival >= bins ) continue ;
omp_set_lock(&locks[ival]) ;
hist[ival]++ ;
omp_unset_lock(&locks[ival]) ;
}
for( ival=0; ival<bins; ++ival ) omp_destroy_lock(&locks[ival]) ;
This program takes exceedingly long to run, so I had to quit it before it could finish. The serial version takes an instant and runs just fine.
What am I doing wrong here?
The compilation is done with g++ using the flags:
-std=c++11 -O2 -fopenmp
Thanks in advance.