【OpenMP】#pragma omp for nowait(nowait子句的作用)

nowait 子句用于消除隐式的 barrier(implicit barrier

隐式 barrier

我们一个知道,在 OpenMP 中,有许多地方有着隐式的 barrier。

例如:

  • parallel 结束后
  • for子句后等等

以下面的代码为例

没有 nowait

int main()
{
#pragma omp parallel
    {
        int id = omp_get_thread_num();
#pragma omp barrier
#pragma omp for
        for (int i = 0; i < 8; i++)
        {
            usleep(1000000 * id); // 等待 id 秒
        }
        cout << "i am " << id << " done\n";
    return 0;
}

输出结果

i am 6 done
i am i am i am 04i am  done
 done
i am 0 done
3i am 7 done
i am i am 1 done
 done
5 done
2 done

可见:
如果没有隐式的 barrier,每个线程应该等待后按次序就输出。但是输出结果却是乱七八糟的,说明各个线程在经历过 barrier 后同时开始输出。

我们使用nowait语句进行对比:

使用 nowait

int main()
{
#pragma omp parallel
    {
        int id = omp_get_thread_num();
#pragma omp barrier
#pragma omp for
        for (int i = 0; i < 8; i++)
        {
            usleep(1000000 * id); // 等待 id 秒
        }
        cout << "i am " << id << " done\n";

#pragma omp for nowait
        for (int i = 0; i < 8; i++)
        {
            usleep(1000000 * id);
        }
        cout << "i am " << id << " done\n";
    }
    return 0;
}

输出结果:

i am 5 done
i am 4 done
i am i am 3 done
i am 1 done
i am 7i am  done
i am 6 done
0 done
2 done
i am 0 done
i am 1 done
i am 2 done
i am 3 done
i am 4 done
i am 5 done
i am 6 done
i am 7 done

实际运行的情况是这样的:

一开始程序等待了 7 秒钟之后,一下子输出8 行(因为有 8 个线程)乱七八糟的输出。
然后每个 1 秒按次序输出一行,因为消除了隐式 barrier,这个线程继续执行下面的代码了。

你可能感兴趣的:(并行计算)