Вперед: 3.3. Переменные окружения OpenMP
Назад: 3.2.12. Синхронизация нитей. Директива FLUSH
К содержанию: Оглавление


3.2.13. Директива THREADPRIVATE

Директива THREADPRIVATE применяется для того, чтобы создать для глобальных переменных языка C/C++ и COMMON блоков языка Фортран их локальные копии в каждой нити.

C/C++:

#pragma omp threadprivate(list)

Fortran:

!$OMP THREADPRIVATE(list)

Директива THREADPRIVATE вызывается сразу после описания переменных и COMMON блоков. При создании параллельных областей каждая нить будет иметь собственную копию этих объектов. Их модификация каждой нитью не будет видна для других нитей. В языке Фортран допускается включение переменных (помимо COMMON блоков) в список list, но тогда они должны быть описаны как SAVE. Если необходимо переменную, объявленную как THREADPRIVATE, инициализировать значением переменной из нити-мастера, то на входе в параллельную область можно использовать опцию COPYIN. Если значение локальной переменной или переменной, объявленной как THREADPRIVATE, необходимо переслать от одной нити всем, работающим в данной параллельной области, для этого можно использовать опцию COPYPRIVATE директивы SINGLE.

Приведем примеры программы использования этой директивы с результатами ее выполнения.

Программа threadprivate.c

 #include <omp.h>
 int a, b, i, tid;
float x;

#pragma omp threadprivate(a, x)
main () {
/* Explicitly turn off dynamic threads */
 omp_set_dynamic(0);
 printf("1st Parallel Region:\n");
#pragma omp parallel private(b,tid)
 {
 tid = omp_get_thread_num();
 a = tid;
 b = tid;
 x = 1.1 * tid +1.0;
 printf("Thread %d:  a,b,x= %d %d %f\n",tid,a,b,x);
 } /* end of parallel section */
 printf("************************************\n");
 printf("Master thread doing serial work here\n");
 printf("************************************\n");
 printf("2nd Parallel Region:\n");
#pragma omp parallel private(tid)
 {
 tid = omp_get_thread_num();
 printf("Thread %d:  a,b,x= %d %d %f\n",tid,a,b,x);
 } /* end of parallel section */
}

Результат работы (выдача в стандартный выходной поток):

1st Parallel Region:
Thread 0:  a,b,x= 0 0 1.000000
Thread 2:  a,b,x= 2 2 3.200000
Thread 3:  a,b,x= 3 3 4.300000
Thread 1:  a,b,x= 1 1 2.100000
************************************
Master thread doing serial work here
************************************
2nd Parallel Region:
Thread 0:  a,b,x= 0 0 1.000000
Thread 3:  a,b,x= 3 0 4.300000
Thread 1:  a,b,x= 1 0 2.100000
Thread 2:  a,b,x= 2 0 3.200000

Программа threadprivate.f

PROGRAM threadprivate
   INTEGER A, B, I, TID, OMP_GET_THREAD_NUM
   REAL*4 X
   COMMON /C1/ A
   SAVE X
!$OMP THREADPRIVATE(/C1/, X) 
C   Explicitly turn off dynamic threads
   CALL OMP_SET_DYNAMIC(.FALSE.)
   PRINT *, '1st Parallel Region:'

!$OMP PARALLEL PRIVATE(B, TID) 
   TID = OMP_GET_THREAD_NUM()
   A = TID
   B = TID
   X = 1.1 * TID + 1.0
   PRINT *, 'Thread',TID,':  A,B,X=',A,B,X
!$OMP END PARALLEL 
   PRINT *, '************************************'
   PRINT *, 'Master thread doing serial work here'
   PRINT *, '************************************'
   PRINT *, '2nd Parallel Region: '
!$OMP PARALLEL PRIVATE(TID) 
   TID = OMP_GET_THREAD_NUM()
   PRINT *, 'Thread',TID,':  A,B,X=',A,B,X
!$OMP END PARALLEL 
   END

Результат работы:

 1st Parallel Region:
 Thread      0 :  A,B,X=     0     0  1.000000  
 Thread      1 :  A,B,X=     1     1  2.100000  
 Thread      3 :  A,B,X=     3     3  4.300000  
 Thread      2 :  A,B,X=     2     2  3.200000  
 ************************************
 Master thread doing serial work here
 ************************************
 2nd Parallel Region: 
 Thread      0 :  A,B,X=     0   32767  1.000000  
 Thread      3 :  A,B,X=     3   32767  4.300000  
 Thread      2 :  A,B,X=     2   32767  3.200000  
 Thread      1 :  A,B,X=     1   32767  2.100000 


Вперед: 3.3. Переменные окружения OpenMP
Назад: 3.2.12. Синхронизация нитей. Директива FLUSH
К содержанию: Оглавление