5

For my understanding, I can use single directive do the same work as using sections just add nowait flags

The following code has no different to me compare to section directive:

    void main(){
    #pragma omp parallel
        {
            int tid = omp_get_thread_num();
    #pragma omp single nowait
            {
                printf("Thread %d in #1 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #2 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #3 single construct.\n", tid);
            }
        }
    }

Can any one give me some examples using sections and single directives in different scenarios?

Charles Chow
  • 1,027
  • 12
  • 26

2 Answers2

5

First and foremost, single and sections directives have clearly different semantic purposes when it comes to reading code and using one to mimic the other may be highly misleading.

Regarding the technicalities, single is the only worksharing directive to support the copyprivate clause, which:

... provides a mechanism to use a private variable to broadcast a value from the data environment of one implicit task to the data environments of the other implicit tasks belonging to the parallel region.

The sections worksharing construct on the other hand supports lastprivate and reduction clauses, which single does not.

Finally, note that your snippet:

#pragma omp single nowait
        {
            printf("Thread %d in #1 single construct.\n", tid);
        }
#pragma omp single nowait
        {
            printf("Thread %d in #2 single construct.\n", tid);
        }
#pragma omp single nowait
        {
            printf("Thread %d in #3 single construct.\n", tid);
        } // No barrier here

does not mimic a sections, but a sections nowait. To mimic a sections you must remember to have the very last single construct maintaining its implicit barrier.

Massimiliano
  • 7,842
  • 2
  • 47
  • 62
  • If i want to make a task manager function, which directive should i choose? – Charles Chow May 09 '14 at 15:09
  • @CharlesChow I don't understand what you mean by "a task manager function". If you want to use task level parallelism, OpenMP 3.X and 4.0 support `task` directives. – Massimiliano May 09 '14 at 16:03
  • I mean a program that registers new tasks and assign each task to threads. You mentioned that I should leave a barrier for single directive, does it means that I just remove `nowait` in the last section of `single`? – Charles Chow May 09 '14 at 16:09
  • 1
    I think it may be of help for you to read this [answer](http://stackoverflow.com/a/13789119/771663) on the differences between sections and tasks. – Massimiliano May 09 '14 at 16:24
2

in some cases, single nowait construct might appear to behave the same way as the sections construct. However, the OpenMP specification only requires that only one thread executes the single construct. It does not require that idle threads take on the other subsequent constructs. You can't simply rely on this behavior for all OpenMP implementations. Most will do what you expect, but there are no guarantees.

The other thing worth mentioning is that most implementations use a ticketing system assign the single regions to threads. The usual code transformation for sections is to map to to the for working sharing construct by translating the sections construct into a for loop and using a switch statement for the section constructs. So, there are some more guarantees about the execution.

Cheers, -michael

Michael Klemm
  • 2,658
  • 1
  • 12
  • 15
  • Am i right saying that even in `sections` the specifications does not `require that idle threads take on the other subsequent constructs`? (See [here](http://stackoverflow.com/a/19306248/771663) for a broader explanation of what I mean, i.e. schedule is implementation defined) – Massimiliano May 09 '14 at 07:41
  • Your are right. If there are less sections that there are threads some might remain idle. With the single pattern above, technically only one thread might execute, although there are several regions that could run in parallel. – Michael Klemm May 09 '14 at 09:56