Reputation: 11
Every time I execute cal() function with the same parameter I get different output. Function g() always calculate the same result for same input. Are threads overwriting any variable?
void cal(uint_fast64_t n) {
Bint num = N(n);
Bint total = 0, i, max_size(__UINT64_MAX__);
for(i = 1; i <= num; i+= max_size){
#pragma omp parallel shared(i,num,total)
{
int id = omp_get_thread_num();
int numthreads = omp_get_num_threads();
Bint sum(0), k;
for(uint64_t j = id; (j < __UINT64_MAX__); j+=numthreads){
k = i+j;
if(k > num){
i = k;
break;
}
sum = sum + g(k);
}
#pragma omp critical
total += sum;
}
}
std::cout << total << std::endl;
}
Upvotes: 0
Views: 297
Reputation: 23711
if(k > num){
i = k;
break;
}
Here you modify the shared variable i
(possibly multiple times in parallel) while other threads may be reading from it (for k = i+j
), all without synchronization. This is a race condition and your code thus has Undefined Behavior.
Upvotes: 7
Reputation: 20818
The value of j
depends on the value of id
. If different threads are used to do the math, you'll get different results.
int id = omp_get_thread_num(); // <---
int numthreads = omp_get_num_threads();
Bint sum(0), k;
for(uint64_t j = id; (j < __UINT64_MAX__); j+=numthreads){ // <---
k = i+j;
if(k > num){
i = k; // <---
break;
}
sum = sum + g(k);
Further, you change i
to k
when k > num
. This can happen much sooner or much later depending on which thread is picked up first to run the inner loop.
You may want to look at this question and answer.
Does an OpenMP ordered for always assign parts of the loop to threads in order, too?
Upvotes: 3