Issue
This Content is from Stack Overflow. Question asked by hiotareq
I’m writing a program to count prime numbers from 2 to N using OpenMP. I wrote this code and while testing it, for example, with N = 10 (OMP_NUM_THREADS=2 ./main 10) I get mostly 4-s but sometimes I get 5-s in my output. It seems like there is a race condition that I cannot see and I don’t now where it is. Can you help me to find this condition and get rid of it?
#include <iostream>
#include <omp.h>
#include <vector>
int main(int argc, char *argv[])
{
if (argc != 2)
return -1;
const unsigned long N = std::atoi(argv[1]);
unsigned counter = 0;
std::vector<bool> numbers(N + 1, true);
numbers[0] = numbers[1] = false;
#pragma omp parallel shared(numbers, counter)
{
#pragma omp single
{
for (size_t i = 2; i * i <= N; ++i)
{
if (numbers[i] == true)
#pragma omp task
{
for (size_t j = i * i; j <= N; j += i)
numbers[j] = false;
}
}
#pragma omp taskwait
}
#pragma omp for reduction(+
: counter)
for (size_t i = 1; i <= N; ++i)
if (numbers[i] == true)
counter++;
}
std::cout << counter << std::endl;
return 0;
}
Solution
Thanks to everyone who commented this question. Laci gave me the answer that I really needed to understand this condition in my code. It is that std::vector<bool>
is a space-efficient specialization, so multiple bit manipulations can cause unexpected result. Solution is to change bool
to char
and you don’t need any more directives so this code works like I expected.
This Question was asked in StackOverflow by hiotareq and Answered by hiotareq It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.