Open MP Force периодическая синхронизация - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь использовать Open MP (C ++) для распараллеливания моего кода параллельного отпуска для симуляций Монте-Карло на трехмерной решетке Изинга.Здесь N (обычно что-то вроде 8) независимых симуляций Монте-Карло проводятся при разных температурах.Моделирование и все его переменные / величины полностью независимы друг от друга.Периодически нужно останавливать симуляции и пытаться обмениваться их конфигурациями - вот в чем проблема.Попытка принудительно остановить потоки (чтобы обмен мог произойти должным образом без одновременного изменения количеств) с использованием барьера завершается неудачей, и компилятор выдает ошибку: «область разделения работы может не быть тесно вложена внутри разделения работы,область критического, упорядоченного, основного или явного задания. "

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

Вот примерный набросок моего кода (пропуская много).

#include "omp.h"//and other headers

#define LSize 10
#define TotalRuns 10
#define MC_WarmUP 10000
#define MC_Samples 50000

using namespace std;
int main()
{
     //rng initialized
     int numruns;
     int Lattice[TotalRuns][LSize][LSize][LSize];//explicit (for swapping)

     omp_set_num_threads(TotalRuns);
     #pragma omp parallel for//run simulations entirely independently
     for (numruns=0;numruns<TotalRuns;numruns++)
     {
          int counter,counter2,counter3;
          double SimEnergy[TotalRuns];
          double Temp;
          //file setup (each simulation also prints its results to file)
          //Lattice[numruns] is initialized to random +1/-1's

          for (counter=70;counter>1;counter++)//i.e for a number of temperatures
          {
              Temp = 0.1*(double)counter + 0.1*(double)numruns;//set temperature
              for (counter2=0;counter2<MC_WarmUP;counter2++)//equilibrate the simulation
              {
                   //perform Monte Carlo iterations here

              }
              for (counter2=0;counter2<(NSamples/SwapSteps);counter2++)//sampling phase
              {
                   for (counter3=0;counter3<SwapSteps;counter3++)//take samples ever SwapSteps interations
                   {
                        //perform Monte Carlo iterations here
                        //save simulation quantities periodically
                   }
                   SimEnergy[numruns] = E_Calc(Lattice,numruns);//calculates the energy of the lattice for a given simulation

                   #pragma omp barrier//need everything to stop at this point
                   #pragma omp single//only one thread does this
                   {
                        //bunch of stuff here but most importantly
                        swap(Lattice[N],Lattice[M])//may occur where N,M are between 0 .. TotalRuns and N!=M.
                   }
              }
              //save averaged data to file
          }
     }
     return 0;
}

Код довольно прост и, возможно, не самый лучший способ решения проблем.Вопрос в том, как я могу заморозить или заблокировать потоки так, чтобы обмен мог происходить без изменения решетки во время операций обмена?Любая помощь приветствуется!

...