c++ - “omp single”和“omp task”如何提供并行性?
问题描述
我对指令感到omp single
困惑omp task
。我已经阅读了几个使用它们的例子。以下示例显示如何使用任务构造来处理链表的元素。
1 #pragma omp parallel
2 {
3 #pragma omp single
4 {
5 for(node* p = head; p; p = p->next)
6 {
7 #pragma omp task
8 process(p);
9 }
10 }
11 }
我无法理解此示例中的并行性。有了omp single
,只有一个线程会执行与单个构造相关的结构化块,对吗?在这个例子中,第 4-10 行是与单个结构相关的结构化块,它只能执行一次,那么为什么我们可以omp task
在这个结构化块中使用呢?它如何以并行方式工作?
解决方案
除了其他答案之外,让我更深入地了解执行期间发生的情况。
1 #pragma omp parallel
2 {
3 #pragma omp single
4 {
5 for(node* p = head; p; p = p->next)
6 {
7 #pragma omp task
8 process(p);
9 }
10 } // barrier of single construct
11 }
在代码中,我标记了在single
构造末尾引入的障碍。
会发生什么:
首先,当遇到parallel
构造时,主线程产生并行区域并创建一堆工作线程。然后你有n 个线程在运行并执行并行区域。
其次,该single
构造选择n 个线程中的任何一个并执行构造的花括号内的代码single
。所有其他n-1 个线程将继续执行第 10 行的屏障。在那里,它们将等待最后一个线程赶上并完成屏障同步。当这些线程在那里等待时,它们不仅在浪费时间,而且还在等待工作到达。
第三,single
构造(“生产者”)选择的线程执行for
循环,并为每次迭代创建一个新任务。然后将该任务放入任务池中,以便另一个线程(屏障中的一个)可以拾取并执行它。一旦生产者完成创建任务,它就会加入屏障,如果任务池中还有任务等待执行,它会帮助其他线程执行任务。
第四,一旦所有任务都以这种方式生成并执行,所有线程都已完成,屏障同步完成。
我在这里和那里进行了一些简化,因为 OpenMP 实现如何执行任务有更多方面,但从概念的角度来看,在您准备好深入了解具体内容之前,您可以想到上述内容正在发生OpenMP API 中的任务调度方面。
推荐阅读
- python - Python 程序生成 TypeError: str object is not callable
- ios - UITableView() 在尝试以编程方式添加时未显示在 UIViewController 中
- android - Android将文件从资产附加到电子邮件
- vb.net - 如何仅清除绘图字符串而不重绘背景图像?
- python - Python:终于给出了 SyntaxError
- php - 在 .htaccess 文件中设置服务器变量是在变量名前加上 REQUEST_
- php - 如何使用 cURL exec PHP 发送文件
- javascript - 如何在鼠标悬停时将 innerHTML 添加到类中?
- c - 当输入的长度超过 C 字符串数组的大小时,有哪些处理方法?
- laravel - 如何在 Laravel 5.5 中重用包含 mysql 获取数据的刀片模板