Task Affinity
4.2. Task Affinity#
The next example illustrates the use of the affinity clause with a task construct. The variables in the affinity clause provide a hint to the runtime that the task should execute “close” to the physical storage location of the variables. For example, on a two-socket platform with a local memory component close to each processor socket, the runtime will attempt to schedule the task execution on the socket where the storage is located.
Because the C/C++ code employs a pointer, an array section is used in the affinity clause. Fortran code can use an array reference to specify the storage, as shown here.
Note, in the second task of the C/C++ code the B pointer is declared shared. Otherwise, by default, it would be firstprivate since it is a local variable, and would probably be saved for the second task before being assigned a storage address by the first task. Also, one might think it reasonable to use the affinity clause affinity(B[:N]) on the second task construct. However, the storage behind B is created in the first task, and the array section reference may not be valid when the second task is generated. The use of the A array is sufficient for this case, because one would expect the storage for A and B would be physically “close” (as provided by the hint in the first task).
//%compiler: clang
//%cflags: -fopenmp
/*
* name: affinity.6
* type: C
* version: omp_5.0
*/
double * alloc_init_B(double *A, int N);
void compute_on_B(double *B, int N);
void task_affinity(double *A, int N)
{
double * B;
#pragma omp task depend(out:B) shared(B) affinity(A[0:N])
{
B = alloc_init_B(A,N);
}
#pragma omp task depend( in:B) shared(B) affinity(A[0:N])
{
compute_on_B(B,N);
}
#pragma omp taskwait
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: affinity.6
! type: F-free
! version: omp_5.0
subroutine task_affinity(A, N)
external alloc_init_B
external compute_on_B
double precision, allocatable :: B(:)
!$omp task depend(out:B) shared(B) affinity(A)
call alloc_init_B(B,A)
!$omp end task
!$omp task depend(in:B) shared(B) affinity(A)
call compute_on_B(B)
!$omp end task
!$omp taskwait
end subroutine