довольно мало, каждый результат обновляется атомарно. Самое главное, вы не хотите читать счетчик в критическом разделе.

я есть код, который выполняет много итераций, и только если условие выполняется, результат итерации сохраняется. Это естественно выражается как цикл while. Я пытаюсь заставить код работать параллельно, так как каждая реализация независима. Итак, у меня есть это:

while(nit<avit){
    #pragma omp parallel shared(nit,avit)
    {
        //do some stuff
        if(condition){
            #pragma omp critical
            {
                nit++;
                \\save results
            }
        }
    }//implicit barrier here
}

и это работает нормально ... но после каждой реализации есть барьер, что означает, что если то, что я делаю в параллельном блоке, занимает больше времени в одной итерации, чем другие, все мои потоки ждут его завершения, а не продолжая следующую итерацию.

Есть ли способ избежать этого барьера, чтобы потоки продолжали работать? Я в среднем тысячи итераций, так что еще несколько не больно (в случае, еслиnit переменная не была увеличена в уже запущенных потоках) ...

Я пытался превратить это в параллель для, но автоматическое увеличение цикла for делаетnit переменная сходит с ума. Это моя попытка:

#pragma omp parallel shared(nit,avit)
{
    #pragma omp for
    for(nit=0;nit<avit;nit++){
        //do some stuff
        if(condition){
            \\save results
        } else {
            #pragma omp critical
            {
                nit--;
            }
        }
    }
}

и он продолжает работать и обходить цикл, как и ожидалось, но мойnit переменная принимает непредсказуемые значения ... как можно было ожидать от увеличения и уменьшения ее различными потоками в разное время.

Я также пытался оставить приращение в цикле for пустым, но он не компилируется, или пытался обмануть мой код, чтобы не иметь приращения в цикле for, например

...
incr=0;
for(nit=0;nit<avit;nit+=incr)
...

но тогда мой код вылетает ...

Есть идеи?

Спасибо

Изменить: Вот рабочий минимальный пример кода в цикле while:

#include <random>
#include <vector>
#include <iostream>
#include <time.h>
#include <omp.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;

int main(){

    int nit,dit,avit=100,t,j,tmax=100,jmax=10;
    vector<double> Res(10),avRes(10);

    nit=0; dit=0;
    while(nit<avit){
        #pragma omp parallel shared(tmax,nit,jmax,avRes,avit,dit) private(t,j) firstprivate(Res)
        {
            srand(int(time(NULL)) ^ omp_get_thread_num());
            t=0; j=0;
            while(t<tmax&&j<jmax){
                Res[j]=rand() % 10;
                t+=Res[j];
                if(omp_get_thread_num()==5){
                    usleep(100000);
                }
                j++;
            }
            if(t<tmax){
                #pragma omp critical
                {
                    nit++;
                    for(j=0;j<jmax;j++){
                        avRes[j]+=Res[j];
                    }
                    for(j=0;j<jmax;j++){
                        cout<<avRes[j]/nit<<"\t";
                    }
                    cout<<" \t nit="<<nit<<"\t thread: "<<omp_get_thread_num();
                    cout<<endl;
                }
            } else{
                #pragma omp critical
                {
                    dit++;
                    cout<<"Discarded: "<<dit<<"\r"<<flush;
                }
            }
        }
    }
    return 0;
}

Я добавилusleep часть для имитации одного потока, занимающего больше времени, чем другие. Если вы запустите программу, все потоки должны ждать завершения потока 5, а затем они начнут следующий запуск. то, что я пытаюсь сделать, - это точно избежать такого ожидания, то есть я бы хотел, чтобы другие потоки выбрали следующую итерацию, не дожидаясь окончания 5.

Ответы на вопрос(1)

Ваш ответ на вопрос