I am parallelizing a code where elements of an array B are a function of elements of an array A. B is smaller than A (i know both sizes in advance) and B[n] is written only if A[n] satisfy a certain condition. A representation of the code would be copy A[n] to B[n] only if A[n] is even, like:
#include<omp.h>
#include<iostream>
bool isEven(int number)
{
if (number%2 == 0)
return true;
else
return false;
}
int main()
{
int array_length = 100;
int A [array_length] = {};
int B [array_length/2] = {};
// fill A with natural numbers
for (int a=0; a<array_length; a++)
{
A[a] = a;
}
int count = 0;
#pragma omp parallel for
for (int n=0; n<array_length; n++)
{
if (isEven(A[n]))
{
#pragma omp critical
{
count++;
B[(count-1)] = A[n];
}
}
}
// print values of b
std::cout << "B is : " ;
for (size_t i = 0; i < array_length/2; i++) {
std::cout << B[i] << ' ';
}
std::cout << std::endl;
return 0;
}
I am trying several combinations of critical and atomic pragmas, as well as increment of count without any success: there is a race condition on count and the final result is garbage in B. Anyone has any idea on how to make it work?
You say that copying A into B is a "representation" of your code. If computing the B elements actually takes some amount of work, then you could let the A loop be done sequentially, and create tasks for the computation of the B elements.