Чем firstprivate и lastprivate отличаются от частных предложений в OpenMP?

Я посмотрел на официальные определения, но я все еще в замешательстве.

firstprivateУказывает, что каждый поток должен иметь свой собственный экземпляр переменной и что переменная должна быть инициализирована значением переменной, поскольку она существует до параллельной конструкции.

Для меня это звучит очень похоже на личное. Я искал примеры, но я не понимаю, как это особенное или как его можно использовать.

lastprivate: Указывает, что версия переменной окружающего контекста установлена ​​равной частной версии любого потока, выполняющего последнюю итерацию (конструкция цикла for) или последний раздел (разделы #pragma).

Я чувствую, что понимаю это немного лучше из-за следующего примера:

#pragma omp parallel
{
   #pragma omp for lastprivate(i)
      for (i=0; i<n-1; i++)
         a[i] = b[i] + b[i+1];
}
a[i]=b[i];

Итак, в этом примере я понимаю, что lastprivate позволяет i должен быть возвращен за пределы цикла как последнее значение.

Я только начал изучать OpenMP сегодня.

3 ответа

Решение

private переменные не инициализируются, т.е. они начинаются со случайных значений, как любая другая локальная автоматическая переменная (и они часто реализуются с использованием автоматических переменных в стеке каждого потока). Возьмите эту простую программу в качестве примера:

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

int main (void)
{
    int i = 10;

    #pragma omp parallel private(i)
    {
        printf("thread %d: i = %d\n", omp_get_thread_num(), i);
        i = 1000 + omp_get_thread_num();
    }

    printf("i = %d\n", i);

    return 0;
}

С четырьмя потоками он выводит что-то вроде:

thread 0: i = 0
thread 3: i = 32717
thread 1: i = 32717
thread 2: i = 1
i = 10

(another run of the same program)

thread 2: i = 1
thread 1: i = 1
thread 0: i = 0
thread 3: i = 32657
i = 10

Это ясно демонстрирует, что ценность i является случайным (не инициализированным) внутри параллельной области, и что любые изменения в нем не видны после параллельной области (то есть переменная сохраняет свое значение до входа в область).

Если i сделан firstprivateзатем он инициализируется значением, которое он имеет перед параллельной областью:

thread 2: i = 10
thread 0: i = 10
thread 3: i = 10
thread 1: i = 10
i = 10

Еще изменения в стоимости i внутри параллельной области не видно после нее.

Вы уже знаете о lastprivate (и это не применимо к простой демонстрационной программе, так как в ней отсутствуют конструкции с разделением рабочих мест).

Так да, firstprivate а также lastprivate это просто особые случаи private, Первый из них приводит к переносу значений из внешнего контекста в параллельную область, а второй - к переносу значений из параллельного региона во внешний контекст. Логическое обоснование этих классов совместного использования данных заключается в том, что внутри параллельной области все частные переменные скрывают переменные из внешнего контекста, т.е. невозможно использовать операцию присваивания для изменения внешнего значения i изнутри параллельной области.

firstprivate а также lastprivate это просто особые случаи private,

Первый из них приводит к переносу значений из внешнего контекста в параллельную область, а второй - к переносу значений из параллельного региона во внешний контекст.

Вы не можете использовать локальную переменную iперед инициализацией программа выдаст ошибку начиная с C++ 14 Standard.

Другие вопросы по тегам