How does the SECTIONS directive in OpenMP distribute work?

匿名 (未验证) 提交于 2019-12-03 02:54:01

问题:

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.

回答1:

I'm pretty surprised that none of the questions here actually answered the OP. As this is one of the first results from google, I think it's important to clarify the topic, especially for beginners who might land on this page and be even more confused. Moreover, some of the answers speak about the nowait clause, which is not even mentioned in the question (I guess, this happened after an edit of the question). This makes things even more confusing.

The OP is surprised that he gets the same id for different sections. While wump is correct is stating that the order is non-deterministic, here the reason is much simpler: the code posted by the OP will never execute in parallel, because the 'parallel' keyword does not appear, unless it is enclosed in a parallel directive. Therefore, it is not a useful example. 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.



回答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.



回答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,



回答4:

You are missing parallel keyword. The parallel keyword triggers the openmp run in parallel.



回答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:

  1. 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
  2. the blocks in the first sections will be executed (in a non-deterministic order) before the blocks in the second sections (also executed in a non-deterministic order). This is because of the implicit barrier at the end of the work-sharing constructs
  3. 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.



回答6:

It may be helpful to add more information to the output line and to add more sections (if you have the thread-count)

#pragma omp parallel sections {     #pragma omp section     {         printf ("section 1 id = %d, \n", omp_get_thread_num());      }     #pragma omp section     {         printf ("section 2 id = %d, \n", omp_get_thread_num());     }     #pragma omp section     {         printf ("section 3 id = %d, \n", omp_get_thread_num());     } } 

Then you may get more interesting output like this:

section 1 id = 4, section 3 id = 3, section 2 id = 1, 

which shows how the sections may be executed in any order, by any available thread.



回答7:

Note that 'nowait' tells the compiler that threads do not need to wait to exit the section. In Fortran 'nowait' goes at the end of the loop or section, which makes this more obvious.



回答8:

If you want really start different threads in different sections, the nowait clause tells compiler that threads do not need to wait to enter a section.

#pragma omp parallel sections nowait {    ... } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!