问题
This question is not a duplicate of fusing nested loops. The OP wants to do a reduction of a maximum value and at the same time store two indices. Fusing the loops will not fix the OPs problem. The OP would still have race conditions on the shared indices and would be accessing the reduced value which does not get merged until the end of the reduction (see my answer for one solution to the OPs problem).
I have a 2D matrix X,X[i][j] means the distance between point i and j.Following code is to find the nearest two point according to their cosine distance in nested loop:
//m,n is the rows,columns of X respectively
int mi,mj;
for(int i=0;i<m;i++)
{
for(int j=i+1;j<n;j++)
{
float distance = cosine_distance(i,j);
if(distance>max_distance)
{
max_distance=distance;
mi=i;
mj=j;
}
}
}
I am new to OpenMP and want to parallel it to get the nearest two point's index i,j. Only adding
#pragma omp parallel for reduction(max : max_distance)
of course not working because the i,j is not rightly recorded.
How to do it? Many Tanks!
回答1:
The reduction on max_distance
is handled by making private version for each thread and merging them after the loop. The problem is that mi
and mj
are shared so you have a race condition writing to them. You need private versions of mi
and mj
as well which you merge in the end.
The following code should do what you want.
#pragma omp parallel
{
float max_distance_private = max_distance;
int mi_private, mj_private;
#pragma omp for
for(int i=0;i<m;i++) {
for(int j=i+1;j<n;j++) {
float distance = cosine_distance(i,j);
if(distance>max_distance_private) {
max_distance_private=distance;
mi_private=i;
mj_private=j;
}
}
}
#pragma omp critical
{
if(max_distance_private>max_distance) {
max_distance = max_distance_private;
mi = mi_private;
mj = mj_private;
}
}
}
来源:https://stackoverflow.com/questions/23950056/how-to-parallel-nested-loop-to-find-the-nearest-two-point-in-openmp