2012-01-25 2 views
4

Друзья, я пытаюсь изучить парадигму openMP. Я использовал следующий код, чтобы понять #omp для прагмы.Неявный барьер в конце #pragma для

int main(void){ 
int tid; 
int i; 

omp_set_num_threads(5); 
#pragma omp parallel \ 
    private(tid) 
{ 
    tid=omp_get_thread_num(); 
    printf("tid=%d started ...\n", tid); 
    fflush(stdout); 

    #pragma omp for 
    for(i=1; i<=20; i++){ 
     printf("t%d - i%d \n", 
       omp_get_thread_num(), i); 
     fflush(stdout); 
    } 

    printf("tid=%d work done ...\n", tid); 
} 

return 0; 

}

В приведенном выше коде, есть неявный барьер в конце #pragma OMP параллельно, то есть все нити 0,1,2,3,4 должны достигнуть там, прежде чем будет следующее утверждение.

Итак, чтобы проверить этот барьер, я включил эту «прагму для» в условие if (tid! = 0), что означает все потоки, кроме потока 0, т.е. 1,2,3,4 должны завершить свою работу в цикле и ждать thread0 бесконечно. Но, к моему удивлению, этого не происходит. Каждый поток выполняет свою итерацию и успешно завершает работу. i.e t1 завершает итерации 5,6,7,8 ---- t2 делает 9,10,11,12 ---- t3 составляет 13,14,15,16, а t4 - 17,18,19,20. Обратите внимание: итерация 1,2,3,4 никогда не была завершена.

Чтобы копать глубже, вместо tid! = 0, я включил ту же самую #pragma для in tid! = 1, а вместо thread0 thread1 обходит барьер. К моему удивлению, программа теперь зависает, и все потоки ждут thread1.

Может кто-нибудь, пожалуйста, объясните мне такое неожиданное поведение. Окончательный код, который повесился:

int main(void){ 
int tid; 
int i; 

omp_set_num_threads(5); 
#pragma omp parallel \ 
    private(tid) 
{ 
    tid=omp_get_thread_num(); 
    printf("tid=%d started ...\n", tid); 
    fflush(stdout); 

    if(tid!=1){ 
     /* worksharing */ 
     #pragma omp for 
     for(i=1; i<=20; i++){ 
      printf("t%d - i%d \n", 
       omp_get_thread_num(), i); 
      fflush(stdout); 
     } 
    }else{ 
     printf("t1 reached here. \n"); 
    } 

    printf("tid=%d work done ...\n", tid); 
} 

return 0; 

}

Я попытался установить я общие или частные, но это не изменило поведение программы.

+0

#pragma omp for обеспечивает способ избавиться от неявного барьера в конце цикла, используя ключевое слово «nowait», но я не использовал его. –

+0

1) 'i' должен быть закрытым. 2) 'omp for' как конструктор совместного использования разделяет работу над уже существующими потоками. Поскольку поток 1 зависает для выполнения цикла совместного использования для цикла, вы блокируете себя. См. [Конструкции совместного использования] (http://msdn.microsoft.com/en-us/library/y0x14tx2.aspx) – Bort

+0

Проверка основных и рабочих потоков и т. П. Больше стиля mpi или pthread. Идея openmp заключается в том, чтобы избавиться от всего этого поворота между мастером и остальным. Конечно, это можно сделать, но вы можете захотеть разделить задачи, а не разбегаться между различными потоками. – Bort

ответ

5

Проблема в том, что по умолчанию стандарт не определен. Из раздела 2.5, строка 21 из OpenMP 3.1 specification (но текст остался тем же более или менее с самого начала):

• Каждый распараллеливание региона должны встретиться всеми потоками в команде или никто вообще.

Место, где omp for - это конструкция для коллекционирования. Так что да, я тоже, как правило, ожидаю, что вы повесите свой код, но компилятор имеет право предположить, что то, что вы делаете, никогда не происходит, и поэтому конечный результат - он иногда зависает, но иногда нет, в зависимости от деталей на каких потоках вы задерживаете - может быть, это не удивительно.

+1

спасибо за ссылку.Даже я знал, что это неопределенное поведение, но по-прежнему известно о фактической реализации библиотеки openMP. Я узнал об этом: «На каждый параллельный блок реализован только один барьер. Таким образом, передача сигналов от одного потока к другому осуществляется через разные барьеры внутри одного и того же параллельного блока». –

+3

, и мы надеемся: «Я узнал об этом:« Я не буду использовать неопределенное поведение в будущем, потому что это вызовет всевозможные неожиданные действия. – Bort

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