Как 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 ответа:
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
внутри параллельной области.