I have the function
void collatz(int startNumber, int endNumber, int* iter, int nThreads)
{
int i, n, counter;
int isodd; /* 1 if n is odd, 0 if even */
#pragma omp parallel for
for (i = startNumber; i <= endNumber; i++)
{
counter = 0;
n = i;
omp_set_num_threads(nThreads);
while (n > 1)
{
isodd = n%2;
if (isodd)
n = 3*n+1;
else
n/=2;
counter++;
}
iter[i - startNumber] = counter;
}
}
It works as I wish when running serial (i.e. compiling without OpenMP or commenting out #pragma omp parallel for
and omp_set_num_threads(nThreads);
). However, the parallel version produces the wrong result and I think it is because the counter
variable need to be set to zero at the beginning of each for loop and perhaps another thread can work with the non-zeroed counter
value. But even if I use #pragma omp parallel for private(counter)
, the problem still occurs. What am I missing?
I compile the program as C89.
Inside your OpenMP parallel region, you are assigning values to the counter
, n
and isodd
scalar variables. These cannot therefore be just shared
as they are by default. You need to pay extra attention to them.
A quick analysis shows that as their values is only meaningful inside the parallel region and only for the current thread, so it becomes clear that they need to be declared private
.
Adding a private( counter, n, isodd )
clause to your #pragma omp parallel
directive should fix the issue.