How does the SECTIONS directive in OpenMP distribute work?
Solution 1
The code posted by the OP will never execute in parallel, because the parallel
keyword does not appear. The fact that the OP got ids different from 0 shows that probably his code was embedded in a parallel directive. However, this is not clear from his post, and might confuse beginners.
The minimum sensible example is (for the first example posted by the OP):
#pragma omp parallel sections
{
#pragma omp section
{
printf ("id = %d, \n", omp_get_thread_num());
}
#pragma omp section
{
printf ("id = %d, \n", omp_get_thread_num());
}
}
On my machine, this prints
id = 0,
id = 1,
showing that the two sections are being executed by different threads.
It's worth noting that however this code can not extract more parallelism than two threads: if it is executed with more threads, the other threads don't have any work to do and will just sit down idle.
Solution 2
The idea of parallel sections is to give the compiler a hint that the various (inner) sections can be performed in parallel, for example:
#pragma omp parallel sections
{
#pragma omp section
{
/* Executes in thread 1 */
}
#pragma omp section
{
/* Executes in thread 2 */
}
#pragma omp section
{
/* Executes in thread 3 */
}
/* ... */
}
This is a hint to the compiler and not guaranteed to happen, though it should. Your output is kind of what is expected; it says that there are #sections being executed in thread id 1, and in thread 2. The output order is non-deterministic as you don't know what thread will run first.
Solution 3
Change the first line from
#pragma omp sections
into
#pragma omp parallel sections
"parallel" directive ensures that the two sections are assigned to two threads. Then, you will receive the following output id = 0, id = 1,
Solution 4
You are missing parallel
keyword.
The parallel
keyword triggers the openmp run in parallel.
Solution 5
According to OpenMP standard 3.1, section 2.5.2 (emphasis mine):
The sections construct is a noniterative worksharing construct that contains a set of structured blocks that are to be distributed among and executed by the threads in a team. Each structured block is executed once by one of the threads in the team in the context of its implicit task.
...
Each structured block in the sections construct is preceded by a section directive except possibly the first block, for which a preceding section directive is optional. The method of scheduling the structured blocks among the threads in the team is implementation defined. There is an implicit barrier at the end of a sections construct unless a nowait clause is specified.
So, applying these rules to your case, we can argue that:
- the different structured blocks identified in a
sections
directive are executed once, by one thread. In other words you have always four prints, whichever the number of threads - the blocks in the first
sections
will be executed (in a non-deterministic order) before the blocks in the secondsections
(also executed in a non-deterministic order). This is because of the implicit barrier at the end of the work-sharing constructs - the scheduling is implementation defined, so that you can't possibly control which thread has been assigned a given section
Your output is thus due to the way your scheduler decided to assign the different blocks to the threads in the team.
Related videos on Youtube
kar
Updated on March 27, 2021Comments
-
kar over 3 years
In OpenMP when using
omp sections
, will the threads be distributed to the blocks inside the sections, or will each thread be assigned to each sections?When
nthreads == 3
:#pragma omp sections { #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } }
Output:
id=1 id=1
But when I execute the following code:
#pragma omp sections { #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } } #pragma omp sections { #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } #pragma omp section { printf ("id = %d, \n", omp_get_thread_num()); } }
Output:
id=1 id=1 id=2 id=2
From these output I can't understand what the concept of sections is in OpenMP.
-
Galaxy over 4 yearsThis article would be interesting to read: jakascorner.com/blog/2016/05/omp-sections.html
-
-
Massimiliano almost 11 yearsThis is just plain wrong.
nowait
means removing the implied barrier at the end of a worksharing construct. There is no barrier on entry. -
Massimiliano over 10 years-1 Your answer contains a lot of inaccuracies. You can't be sure that different sections are assigned to different threads. The output order is non-deterministic only inside a single
sections
construct, not among two differentsections
(implicit barrier at the end of the construct) -
Rotom92 over 9 yearsI agree with Massimiliano; Moreover, if u try to compile nowait with parallel it says that 'nowait' is not valid for 'omp parallel sections nowait'
-
ajaysinghnegi over 4 yearsSir, In the comment of the accepted answer, you commented
You can't be sure that different sections are assigned to different threads
. But, the 1st para in section 2.5.2 that you've referred speaks the similar thing. What's the difference? -
Massimiliano over 4 yearsThis answer does not explain why the OP shows
id=1
andid=2
. It's very likely the program the OP posted was running in parallel. -
Massimiliano over 4 years@jos The difference is that the standard does not prescribe how blocks are distributed.
The method of scheduling the structured blocks among the threads in the team is implementation defined
. The OP shows that in a particular run the 2 blocks of the firstsections
are assigned both to thread 1, likewise for thread 2 on the blocks for the second section.