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


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

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

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

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

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

#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.

2 53

2 ответа:

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.

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