nowait Clause
3.7. nowait Clause#
clauses!nowait nowait nowait clause nowait clause
If there are multiple independent loops within a parallel region, you can use the nowait clause to avoid the implied barrier at the end of the loop construct, as follows:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nowait.1
* type: C
*/
#include <math.h>
void nowait_example(int n, int m, float *a, float *b, float *y, float *z)
{
int i;
#pragma omp parallel
{
#pragma omp for nowait
for (i=1; i<n; i++)
b[i] = (a[i] + a[i-1]) / 2.0;
#pragma omp for nowait
for (i=0; i<m; i++)
y[i] = sqrt(z[i]);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nowait.1
! type: F-fixed
SUBROUTINE NOWAIT_EXAMPLE(N, M, A, B, Y, Z)
INTEGER N, M
REAL A(*), B(*), Y(*), Z(*)
INTEGER I
!$OMP PARALLEL
!$OMP DO
DO I=2,N
B(I) = (A(I) + A(I-1)) / 2.0
ENDDO
!$OMP END DO NOWAIT
!$OMP DO
DO I=1,M
Y(I) = SQRT(Z(I))
ENDDO
!$OMP END DO NOWAIT
!$OMP END PARALLEL
END SUBROUTINE NOWAIT_EXAMPLE
In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the nowait clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop.
Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from 0 to n-1 (from 1 to N in the Fortran version), while the iteration space of the last loop is from 1 to n (2 to N+1 in the Fortran version).
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nowait.2
* type: C
*/
#include <math.h>
void nowait_example2(int n, float *a, float *b, float *c, float *y, float
*z)
{
int i;
#pragma omp parallel
{
#pragma omp for schedule(static) nowait
for (i=0; i<n; i++)
c[i] = (a[i] + b[i]) / 2.0f;
#pragma omp for schedule(static) nowait
for (i=0; i<n; i++)
z[i] = sqrtf(c[i]);
#pragma omp for schedule(static) nowait
for (i=1; i<=n; i++)
y[i] = z[i-1] + a[i];
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nowait.2
! type: F-free
SUBROUTINE NOWAIT_EXAMPLE2(N, A, B, C, Y, Z)
INTEGER N
REAL A(*), B(*), C(*), Y(*), Z(*)
INTEGER I
!$OMP PARALLEL
!$OMP DO SCHEDULE(STATIC)
DO I=1,N
C(I) = (A(I) + B(I)) / 2.0
ENDDO
!$OMP END DO NOWAIT
!$OMP DO SCHEDULE(STATIC)
DO I=1,N
Z(I) = SQRT(C(I))
ENDDO
!$OMP END DO NOWAIT
!$OMP DO SCHEDULE(STATIC)
DO I=2,N+1
Y(I) = Z(I-1) + A(I)
ENDDO
!$OMP END DO NOWAIT
!$OMP END PARALLEL
END SUBROUTINE NOWAIT_EXAMPLE2