Oracle Solaris Studio 12.2:OpenMP API 用户指南

4.3 在嵌套并行区域中使用 OpenMP 库例程

在嵌套并行区域中调用以下 OpenMP 例程需要仔细斟酌。

- omp_set_num_threads()
- omp_get_max_threads()
- omp_set_dynamic()
- omp_get_dynamic()
- omp_set_nested()
- omp_get_nested()

"set" 调用只影响调用线程所遇到的处于同一嵌套级别或内部嵌套级别的后续并行区域。它们不影响其他线程遇到的并行区域。

"get" 调用将返回由调用线程设置的值。当某个线程成为执行并行区域的组的主线程后,所有其他的组成员会继承该主线程的值。当主线程退出嵌套并行区域,并继续执行封闭并行区域时,该线程的值会恢复为刚执行嵌套并行区域之前封闭并行区域中的值。


示例 4–2 在并行区域中调用 OpenMP 例程


#include <stdio.h>
#include <omp.h>
int main()
{
    omp_set_nested(1);
    omp_set_dynamic(0);
    #pragma omp parallel num_threads(2)
    {
        if (omp_get_thread_num() == 0)
            omp_set_num_threads(4);       /* line A */
        else
            omp_set_num_threads(6);       /* line B */

        /* The following statement will print out
         *
         * 0: 2 4
         * 1: 2 6
         *
         * omp_get_num_threads() returns the number
         * of the threads in the team, so it is
         * the same for the two threads in the team.
         */
        printf("%d: %d %d\n", omp_get_thread_num(),
               omp_get_num_threads(),
               omp_get_max_threads());

        /* Two inner parallel regions will be created
         * one with a team of 4 threads, and the other
         * with a team of 6 threads.
         */
        #pragma omp parallel
        {
            #pragma omp master
            {
                /* The following statement will print out
                 *
                 * Inner: 4
                 * Inner: 6
                 */
                printf("Inner: %d\n", omp_get_num_threads());
            }
            omp_set_num_threads(7);      /* line C */
        }

        /* Again two inner parallel regions will be created,
         * one with a team of 4 threads, and the other
         * with a team of 6 threads.
         *
         * The omp_set_num_threads(7) call at line C
         * has no effect here, since it affects only
         * parallel regions at the same or inner nesting
         * level as line C.
         */

        #pragma omp parallel
        {
            printf("count me.\n");
        }
    }
    return(0);
}

编译和运行此程序会产生一种以下可能的结果:


% a.out
0: 2 4
Inner: 4
1: 2 6
Inner: 6
count me.
count me.
count me.
count me.
count me.
count me.
count me.
count me.
count me.
count me.