critical Construct
9.1. critical Construct#
The following example includes several critical constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a critical region. Because the two queues in this example are independent, they are protected by critical constructs with different names, xaxis and yaxis .
//%compiler: clang
//%cflags: -fopenmp
/*
* name: critical.1
* type: C
*/
int dequeue(float *a);
void work(int i, float *a);
void critical_example(float *x, float *y)
{
int ix_next, iy_next;
#pragma omp parallel shared(x, y) private(ix_next, iy_next)
{
#pragma omp critical (xaxis)
ix_next = dequeue(x);
work(ix_next, x);
#pragma omp critical (yaxis)
iy_next = dequeue(y);
work(iy_next, y);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: critical.1
! type: F-fixed
SUBROUTINE CRITICAL_EXAMPLE(X, Y)
REAL X(*), Y(*)
INTEGER IX_NEXT, IY_NEXT
!$OMP PARALLEL SHARED(X, Y) PRIVATE(IX_NEXT, IY_NEXT)
!$OMP CRITICAL(XAXIS)
CALL DEQUEUE(IX_NEXT, X)
!$OMP END CRITICAL(XAXIS)
CALL WORK(IX_NEXT, X)
!$OMP CRITICAL(YAXIS)
CALL DEQUEUE(IY_NEXT,Y)
!$OMP END CRITICAL(YAXIS)
CALL WORK(IY_NEXT, Y)
!$OMP END PARALLEL
END SUBROUTINE CRITICAL_EXAMPLE
The following example extends the previous example by adding the hint clause to the critical constructs.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: critical.2
* type: C
* version: omp_5.0
*/
#include <omp.h>
int dequeue(float *a);
void work(int i, float *a);
void critical_example(float *x, float *y)
{
int ix_next, iy_next;
#pragma omp parallel shared(x, y) private(ix_next, iy_next)
{
#pragma omp critical (xaxis) hint(omp_sync_hint_contended)
ix_next = dequeue(x);
work(ix_next, x);
#pragma omp critical (yaxis) hint(omp_sync_hint_contended)
iy_next = dequeue(y);
work(iy_next, y);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: critical.2
! type: F-fixed
! version: omp_5.0
SUBROUTINE CRITICAL_EXAMPLE(X, Y)
USE OMP_LIB ! or INCLUDE "omp_lib.h"
REAL X(*), Y(*)
INTEGER IX_NEXT, IY_NEXT
!$OMP PARALLEL SHARED(X, Y) PRIVATE(IX_NEXT, IY_NEXT)
!$OMP CRITICAL(XAXIS) HINT(OMP_SYNC_HINT_CONTENDED)
CALL DEQUEUE(IX_NEXT, X)
!$OMP END CRITICAL(XAXIS)
CALL WORK(IX_NEXT, X)
!$OMP CRITICAL(YAXIS) HINT(OMP_SYNC_HINT_CONTENDED)
CALL DEQUEUE(IY_NEXT,Y)
!$OMP END CRITICAL(YAXIS)
CALL WORK(IY_NEXT, Y)
!$OMP END PARALLEL
END SUBROUTINE CRITICAL_EXAMPLE