B6 - synchronisation directives

int counter = 0;
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
   counter++;
}
printf("Counter = %d\n", counter); 

critical

int counter = 0;
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
    #pragma omp critical
    {
        counter++;
    }
}
printf("Counter = %d\n", counter);

atomic

int counter = 0;
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
    #pragma omp atomic
    counter++;
}
printf("Counter = %d\n", counter);

reduction clauses

int sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < 1000; i++) {
    sum += i;
}

optimising critical section

#pragma omp parallel for
for (int i = 0; i < N; i++) {
	#pragma omp critical
	{
		if (a[i] > a_max) {
			a_max = a[i];
		}
	}
}
#pragma omp parallel for
for (int i = 0; i < N; i++) {
    if (a[i] > a_max) {
        #pragma omp critical
        {
            if (a[i] > a_max) {
                a_max = a[i];
            }
        }
    }
}

naming critical sections

#pragma omp parallel for
for (i = 0; i  < N; i++) {
	if (a[i] > a_max) {
		#pragma omp critical (maxlock)
			if (a[i] > a_max) a_max = a[i]; 
	}
	if (a[i] < a_min) {
		#pragma omp critical (minlock)
			if (a[i] < a_min) a_min = a[i]; 
	}
}

locks

omp_lock_t writelock;
omp_init_lock(&writelock);

#pragma openmp parallel for
for (i = 0; i < x; i++) {
	// ...
	omp_set_lock(&writelock);
	// ...
	omp_unset_lock(&writelock);
	// ...
}

omp_destroy_lock(&writelock);