Неявный барьер в конце #pragma для - PullRequest
6 голосов
/ 25 января 2012

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

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 должны завершить свою работу в цикле и ждать потока 0 бесконечно.Но, к моему удивлению, этого не происходит.Каждый поток выполняет свою итерацию и успешно завершается.т.е. 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 для в tid! = 1, то есть вместо thread0, thread1обходит барьер.К моему удивлению, программа теперь зависает, и все потоки ожидают поток 1.

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

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;

}

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

1 Ответ

6 голосов
/ 25 января 2012

Проблема здесь в том, что поведение не определено стандартом.Из Раздела 2.5, строка 21 спецификации OpenMP 3.1 (но текст остался более или менее с самого начала):

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

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

...