2016-04-06 4 views
0

У меня есть несколько функций, которые необходимо применять последовательно к матрице некоторых структур. Для одного потока я использую следующий код:OpenMP с вложенными циклами

for(int t = 0; t < maxT; ++t) 
{ 
    for(int i = 0; i < maxI; ++i) 
     for(int j = 0; j < maxJ; ++j) 
      function1(i, j); 

    for(int i = 0; i < maxI; ++i) 
     for(int j = 0; j < maxJ; ++j) 
      function2(i, j); 
} 

Теперь я пытаюсь распараллелить этот код:

#pragma omp parallel 
{ 
    for(int t = 0; t < maxT; ++t) 
    { 
     #pragma omp single 
     function3(); // call this function once (once for each iteration of t) 
     #pragma omp for 
     for(int i = 0; i < sizeI; ++i) 
      for(int j = 0; j < sizeJ; ++j) 
       function1(i, j); 

     #pragma omp for 
     for(int i = 0; i < sizeI; ++i) 
      for(int j = 0; j < sizeJ; ++j) 
       function2(i, j); 
    } 
} 

это правильно? Работает ли это способом повторного использования потоков (не создавая новую команду нитей в основном цикле)?

Обновление: Явный барьер действительно не нужен.

На самом деле кажется, что я был смущен, когда задал этот вопрос - пример кода работает правильно. Теперь возникает вопрос: можно ли вызывать функцию (прокомментированную строку в коде) после #pragma omp parrallel (не вызывать функцию3 в каждом потоке на каждой итерации). Существует #pragma omp atomic для вызова операторов инкремента и некоторых других, но если я хочу вызвать один экземпляр произвольной функции (или, как правило, выполнить блок кода)?

Комментарий Марка. Я предполагаю, что буду обрабатывать расы данных в своих параллельных функциях. Единственный вопрос здесь: контейнеры stl не просто потокобезопасны при использовании OpenMP? то есть, если я хочу push_back() в std :: list из нескольких потоков, мне все равно нужно заблокировать этот список вручную.

Обновление 2: Я обнаружил, что для запуска одиночного действия в параллельном разделе необходимо использовать #pragma omp single. Итак, этот вопрос закрыт.

+1

* Правильно? * Возможно. Возможно, нет. Похоже, что ваши функции действуют через побочные эффекты. Эти побочные эффекты могут реализовывать расы данных ... –

ответ

2

Да, это создаст одну параллельную область, где каждый поток будет перебирать t по внешнему циклу и разбивать работу итераций циклов i среди потоков.

Обратите внимание, что в конце #pragma omp for есть неявный барьер, поэтому вам не нужно также писать свой явный барьер. Этот неявный барьер можно удалить, используя предложение nowait (то есть #pragma omp for nowait).

Смежные вопросы