Зависимость задач OpenMP игнорируется? - PullRequest
0 голосов
/ 04 марта 2019

Прежде всего, вот пример кода:

#include <iostream>

int main()
{
    int x = 100;
    #pragma omp parallel
    {
        #pragma omp single
        {
            #pragma omp task depend (in: x)
            { x += 1; }

            #pragma omp task depend (out: x)
            { x *= 2; }            
        }
    }
    printf("x = %d\n", x); // prints 202
}

Из того, что я понимаю, task depend(in: x) должен ждать чего-либо с depend(out: x), но, похоже, это не то, что происходит.

В данном конкретном случае, вывод равен 202, что предполагает, что x был сначала увеличен, а затем удвоен.

На самом деле, я пробовал и вход, и выход, и выход / вход, а такжекак переключение порядка, в котором определяются сами задачи.Независимо от зависимостей ввода / вывода, задачи всегда выполняются сверху вниз.

Не понимаю ли я значение task depend?

1 Ответ

0 голосов
/ 05 марта 2019

Реализация работает правильно.

Помимо порядка, который устанавливается с помощью предложения depend, на создание зависимости также влияет положение создания задачи в исходном коде.

В вашем примере первая задача имеет зависимость in от переменной x.Поскольку в очередях нет существующей задачи, которая имеет зависимость out или inout для той же переменной, задача готова к немедленному выполнению, и реализация, скорее всего, сделает это даже до того, как встретится вторая задача.

Если я обменяюсь двумя заданиями:

int main()
{
    int x = 100;
    #pragma omp parallel
    {
        #pragma omp single
        {
            #pragma omp task depend (out: x)
            { x *= 2; }
            #pragma omp task depend (in: x)
            { x += 1; }
        }
    }
    printf("x = %d\n", x); // prints 201
}

Код печатает 201, как и ожидалось.Я проверил это с помощью Intel Compiler 18.0.3.

Правильное моделирование зависимостей задач для вашего кода выглядело бы так:

int main()
{
    int x = 100;
    #pragma omp parallel
    {
        #pragma omp single
        {
            #pragma omp task depend (inout: x)
            { x *= 2; }
            #pragma omp task depend (inout: x)
            { x += 1; }
        }
    }
    printf("x = %d\n", x); // prints 201
}

Код по-прежнему печатает 202, но теперьзависимости корректно моделируют фактическое использование x: задача 1 считывает старое значение x и изменяет его, поэтому она должна использовать зависимость inout.Задача 2 также читает x и изменяет ее, поэтому она также должна использовать зависимость inout.

...