Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top