I am trying to understand the exact difference between #pragma omp critical
and #pragma omp single
in OpenMP:
Microsoft definitions for these are:
So it means that in both, the exact section of code afterwards would be executed by just one thread and other threads will not enter that section e.g. if we print something, we will see the result on screen once, right?
How about the difference? It looks that critical take care of time of execution, but not single! But I don't see any difference in practice! Does it mean that a kind of waiting or synchronization for other threads (which do not enter that section) is considered in critical, but there is nothing that holds other threads in single? How it can change the outcome in practice?
I appreciate if anyone can clarify this to me especially by an example. Thanks!
single
and critical
are two very different things. As you mentioned:
single
specifies that a section of code should be executed by single thread (not necessarily the master thread)critical
specifies that code is executed by one thread at a timeSo the former will be executed only once while the later will be executed as many times as there are of threads.
For example the following code
int a=0, b=0;
#pragma omp parallel num_threads(4)
{
#pragma omp single
a++;
#pragma omp critical
b++;
}
printf("single: %d -- critical: %d\n", a, b);
will print
single: 1 -- critical: 4
I hope you see the difference better now.
For the sake of completeness, I can add that:
master
is very similar to single
with two differences:
master
will be executed by the master only while single
can be executed by whichever thread reaching the region first; andsingle
has an implicit barrier upon completion of the region, where all threads wait for synchronization, while master
doesn't have any.atomic
is very similar to critical
, but is restricted for a selection of simple operations.I added these precisions since these two pairs of instructions are often the ones people tend to mix-up...