OpenMP и Nested для циклов с инструкциями continue - PullRequest
1 голос
/ 01 февраля 2012

У меня есть следующий код:

int myArray[] = {0, 0, 0, 0, 0, 0};
double EV = 0;
for(short a1 = 1; a1 <= 6; ++a1)
{
    ++myArray[a1-1];
    if(....)
    {
        --myArray[a1-1];
        continue;
    }
    EV = myEVFunc();
    if(EV...)
    {

        for(short a2 = 1; a2 <=6 ; ++a2)
        {
            ++myArray[a2-1];
            if(....)
            {
                --myArray[a2-1];
                continue;
            }
            EV = myEVFunc();
            if(EV...)
            {
                for(short a3 = 1; a3 <= 6; ++a3)
                {
                    ++myArray[a3-1];
                    if(....)
                    {
                        --myArray[a3-1];
                        continue;
                    }
                    EV = myEVFunc();
                }
            }
        }
    }
}

Я пытаюсь использовать OpenMP для распараллеливания циклов. код компилируется нормально, когда я помещаю #pragma omp parallel for перед самой внешней петлей. Однако это дает неверные результаты. Я подозреваю две проблемы: операторы continue внутри циклов и тот факт, что во вложенных циклах есть общие переменные. Можно ли использовать OpenMP с этим фрагментом кода, если да, может кто-нибудь дать мне правильный синтаксис. Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 01 февраля 2012

Я укажу пару очевидных вещей:

1.) double EV = 0; объявляется вне внешнего цикла. Поэтому оно будет доступно всем потокам. Таким образом, у вас будет состояние гонки при EV = myEVFunc(); и при каждом доступе к EV.

Решением этого является объявление его внутри цикла. Это сделает его приватным для каждого потока.

#pragma omp parallel for
    for(short a1 = 1; a1 <= 6; ++a1)
    {
        ++myArray[a1-1];
        if(....)
        {
            --myArray[a1-1];
            continue;
        }
        double EV = myEVFunc();
        if(EV...)
        ...

2.) Другая (сортирующая) проблема заключается в том, что ваш внешний цикл имеет только 6 итераций. Таким образом, вы не получите более 6 потоков. Кроме того, вы можете получить проблемы с балансировкой нагрузки, скажем, с 4 ядрами ...

1 голос
/ 01 февраля 2012

Вы также можете использовать приватный поток, если это больше того, что вам нужно

Это даст личную копию переменной EV каждому потоку.Первоначально он будет неинициализирован в этих потоках, если только вы не используете copyin.

Без копирования директива будет выглядеть следующим образом:

#pragma omp parallel for private(EV) 

Это позволяет избежать состояния гонки и позволяет EV действовать независимо в каждом потоке

0 голосов
/ 01 февраля 2012

у вас также есть состояние гонки с доступом к массиву, например ++myArray[a1-1]; и ++myArray[a2-1]; из разных тем. Кроме того, вам нужно объявить все счетчики циклов закрытыми, a1 (по умолчанию закрыто из-за прагмы omp для, но не), a2, a3 ..

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...