Используя c ++ openmp 3.1, я реализовал максимальное сокращение, в котором хранится максимальное значение целочисленной переменной (оценки) вектора объектов (объектов). Но я также хочу сохранить векторный индекс, чтобы получить доступ к объекту (ам) с максимальной оценкой.
Моя текущая неудачная реализация выглядит так:
//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
}
}
}
Код компилируется и запускается. максимальный показатель рекордов найден, но бестант получает случайный индекс. Муравей, связанный с самой быстрой нитью, хранится в бестанте.
bestscore начинается со значения 0, поэтому в большинстве случаев s [ant] .score будет иметь более высокий балл, а bestscore и bestant обновляются.
Я думаю, что мне нужен оператор сокращения для бестанта, как «при обновлении bestscore».
Попробуй это
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;
}
}
}
Два наблюдения:
Я думаю, вам нужно только сравнить bestscore_private
в bestscore
когда его значение изменяется, таким образом количество сравнений уменьшается.
Кроме того, по крайней мере в сегодняшних omp вы можете использовать критический раздел внутри если условный, то этот способ сравнения между bestscore_private
bestscore
будет проводиться параллельно и нечастое (надеюсь, что так) обновление до bestscore
будет осуществляться в критической манере.
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;
}
}
}
}
}