omp барьеры блокируют

У меня есть код:

#include <stdio.h>
#include <omp.h>

static void func()
{
    char t[30];
    sprintf(t,"%d %d\n",omp_get_num_threads(),omp_get_thread_num());
    write(1,t,strlen(t));
    write(1,"checkpoint 1\n",13);
    #pragma omp barrier 
    write(1,"checkpoint 2\n",13);
    #pragma omp barrier
    write(1,"checkpoint 3\n",13);
    #pragma omp barrier
    write(1,"checkpoint 4\n",13);
}

int main()
{
    int i;
#pragma omp parallel for
    for(i=0;i<2;i++)
    {
       func();
    }
} 

и вывод:

8 1
8 0
checkpoint 1
checkpoint 1
checkpoint 2
checkpoint 2
[here my program blocks].

если я меняю 2 на 8, это работает. но я хочу иметь 2 в цикле for.

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


person tigger    schedule 08.06.2015    source источник
comment
Барьеры OpenMP являются глобальными среди потоков в команде. Вы не можете синхронизировать только два из N потоков на барьере. Вот почему это работает, когда вы явно устанавливаете количество потоков равным двум.   -  person Hristo Iliev    schedule 09.06.2015


Ответы (1)


Барьеры используются для синхронизации всех потоков в группе. Все поступающие потоки будут заблокированы до тех пор, пока все потоки не достигнут барьера. Тогда и только тогда все они могут продолжаться.

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

У вас есть барьер в функции func, который выполняется один раз за итерацию вашего параллельного цикла. Поскольку OpenMP должен назначать эти итерации потокам, не все из них могут получить одинаковое количество итераций (в вашем случае они получают одно и то же число для количества потоков 2 - одна итерация для каждого потока, поэтому ваша программа тогда прекращается). Это неравное количество барьеров блокирует вашу программу.

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

person mastov    schedule 10.06.2015
comment
Я не думаю, что этот ответ правильно объясняет поведение, описанное в вопросе. Причины, указанные в этом ответе, объяснят, почему программа может заблокироваться после двухкратной печати checkpoint 1. Но в этом случае программа печатает checkpoint 1 два раза, затем печатает checkpoint 2 два раза, а затем блокируется. Вывод checkpoint 2 должен означать, что все потоки достигли и преодолели первый барьер. Похоже, что потоки затем блокируются на втором барьере. Странный. - person jcsahnwaldt Reinstate Monica; 18.11.2018
comment
PS: Думаю, я должен добавить, что ваш ответ является хорошим объяснением барьеров и проблем, подобных описанным в вопросе. Проголосовать. - person jcsahnwaldt Reinstate Monica; 18.11.2018
comment
@jcsahnwaldt Вау, ты прав, я не обратил на это внимание. В любом случае, я снова запустил код, и он заблокировался на первом барьере. У меня не получилось дотянуться до второго, как я ни крутил параметры и тайминги. И это действительно единственное, что может произойти с приведенным выше кодом. Так что я предполагаю, что между опубликованной версией кода и выходной версией было просто несоответствие. Это часто случается, когда люди пытаются заставить что-то работать и продолжают модифицировать код. Но спасибо, что указали! - person mastov; 28.11.2018