Синхронизация конструкции внутри прагмы для - PullRequest
0 голосов
/ 25 мая 2010

У меня есть программный блок вроде:

    for (iIndex1=0; iIndex1 < iSize; iIndex1++)
    {
        for (iIndex2=iIndex1+1; iIndex2 < iSize; iIndex2++)
        {   
            iCount++;
            fDist =(*this)[iIndex1].distance( (*this)[iIndex2] );
            m_oPDF.addPairDistance( fDist );

            if ((bShowProgress) && (iCount % 1000000 == 0))
                xyz_exception::ui()->progress( iCount, (size()-1)*((size()-1))/2 );

        }
    }
} 
}

Я попытался распараллелить внутренний и внешний цикл и поместить iCount в критическую область. Каков наилучший подход для распараллеливания этого? Если я оберну iCount omp single или omp atomic, тогда код выдаст ошибку, и я выяснил, что это будет недопустимо внутри omp для Я полагаю, я добавляю много посторонних вещей, чтобы это парализовать. Нужен совет ...

Спасибо

Саянский

Ответы [ 3 ]

1 голос
/ 25 мая 2010

Если я правильно интерпретирую ваши намерения, вы хотите использовать iCount, чтобы сообщить своей программе, когда (каждые 10 ^ 6 операций) обновлять пользовательский интерфейс?И iCount является глобальным, все потоки должны совместно использовать значение, и вы хотите сохранить его согласованность?

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

Если вам не нравится идея, что все потоки отправляют сообщения в пользовательский интерфейс, возможно, это может сделать только один поток;если один поток проходит 1/4 пути через программу, то и другие потоки (приблизительно).

0 голосов
/ 31 мая 2010

Большое спасибо, Марк. Я удалил iCount и сделал внешний цикл параллельным, но копаю код, так как не наблюдаю ускорения по сравнению с последовательной версией.

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

  1. Создание параллельного внутреннего цикла

    Параллельная прагма
    для (... я ...)
    прагма помпа для
    для (... J ...)

  2. Создание параллельного внешнего цикла (просто ... параллель прагмы для ... перед внешним циклом)

  3. Использование Collapse (для Omp 3.0)

Спасибо
Саян

0 голосов
/ 26 мая 2010

Еще раз спасибо, Марк. Я попробовал подходы, которые вы предложили. Я поместил сокращение (+: iCount), а также попытался обернуть iCount ++ вокруг прагматической критичности, и да, это снижение производительности (также я не видел ускорения). Кроме того, я позволил одному потоку обрабатывать iCount, но подходы, которые я использовал, не приводят к ускорению.

Я ожидал, что если я добавлю прагму для внутреннего цикла и объявлю iCount как переменную редукции, я бы заметил некоторое ускорение. Моя цель - параллельное выполнение этих операторов для пары Index1, Index2:

        fDist =(*this)[iIndex1].distance( (*this)[iIndex2] );
        m_oPDF.addPairDistance( fDist );

, что может заметно повлиять на время выполнения программы.

...