2013-03-08 2 views
48

Я просмотрел официальные определения, но я все еще довольно смущен.Как firstprivate и lastprivate отличаются от частных предложений в OpenMP?

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

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

lastprivate: Указывает, что версия контексте вшита в переменной устанавливается равной частной версии от какой нить выполняет последней итерации (для цикла конструкт) или последнюю секцию (#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 сегодня.

ответ

103

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

#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 изнутри параллельной области.

+1

Это отличный ответ! Большое спасибо! – SaiyanGirl

+0

Ну, я бы сказал, что 'firstprivate' и' lastprivate' являются ОЧЕНЬ особыми случаями 'private'. Обычно вам даже не нужно использовать 'private' (просто определите переменную внутри параллельного блока), возможно, затеняя внешнюю область. Интересным является использование объектов C++ в качестве автоматических переменных 'firstprivate' - они будут инициализированы путем создания копии, один раз и уничтожены после блока, и вам не нужно знать количество потоков заранее - так как многие копии будут при необходимости создаваться. –

+0

Такой отличный пример! Нравится это больше всего. Цените Христо. – Fusionmate

1

firstprivate и lastprivate - это только особые случаи private.

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

+0

Вы могли бы предоставить какие-либо справки об этом? –

Смежные вопросы