问题
Using c++ openmp 3.1 I implemented a max reduction which stores the maximum value of integer variable (score) of an vector of objects (s). But I also want to store the vector index to acces the (s) object with the maximum score. My current unsuccesfull implementation looks like this:
//s is a vector of sol objects which contain apart from other variables an integer score variable s[].score
int bestscore = 0;
int bestant = 0;
#pragma omp parallel shared(bestant)
{//start parallel session
#pragma omp for nowait reduction(max : bestscore)
for (int ant = 0; ant<maxsols; ++ant) // for all ants
{
//procedures on s[ant] object which update the int s[ant].score
if (s[ant].score > bestscore)
{
//find the object with the highest score
bestscore = s[ant].score;
bestant = ant;//i also want know which ant has the highest score
}
}
}
The code compiles and runs. the maximum bestscore is found but bestant gets a random index. The ant linked to the fastest thread to finish gets stored in bestant. bestscore start with a value of 0 so in most cases s[ant].score will have a higher score and bestscore and bestant are updated. I think I need a reduction operator for bestant like "on update of bestscore".
回答1:
Try this
int bestscore = 0;
int bestant = 0;
#pragma omp parallel
{
int bestscore_private = 0;
int bestant_private = 0;
#pragma omp for nowait
for (int ant = 0; ant<maxsols; ++ant) {
if (s[ant].score > bestscore_private) {
bestscore_private = s[ant].score;
bestant_private = ant;
}
}
#pragma omp critical
{
if(bestscore_private>bestscore) {
bestscore = bestscore_private;
bestant = besant_private;
}
}
}
回答2:
Two observations:
I think you only need to compare
bestscore_private
tobestscore
when its value is changed, this way the number of comparisons is reduced.Also, at least in todays omp you can utilize a critical section inside the if conditional, this way comparisons between
bestscore_private
abestscore
would be carried out in parallel and the infrequent (hope so) update tobestscore
will be carried out in a critical manner.int bestscore = 0; int bestant = 0; #pragma omp parallel {
int bestscore_private = 0; int bestant_private = 0; #pragma omp for nowait for (int ant = 0; ant<maxsols; ++ant) { if (s[ant].score > bestscore_private) { bestscore_private = s[ant].score; bestant_private = ant; if(bestscore_private>bestscore){ #pragma omp critical { bestscore = bestscore_private; bestant = besant_private; } } } }
}
来源:https://stackoverflow.com/questions/24782038/omp-max-reduction-with-storage-of-index