当杂注内部有编译指示时,OpenMP 中会发生什么?
What happens in OpenMP when there's a pragma for inside a pragma for?
在#pragma omp parallel
开始时创建了一堆线程,然后当我们到达#pragma omp for
时分配工作负载。如果这个for循环里面有一个for循环,并且我在它前面也放了一个#pragma omp for
,会发生什么?每个线程都创建新线程吗?如果没有,分配给哪些线程这个任务?在这种情况下到底会发生什么?
默认情况下,不为内部循环生成线程。它是通过到达它的线程顺序完成的。
这是因为嵌套在默认情况下是禁用的。但是,如果您通过omp_set_nested()
启用嵌套,那么将生成一组新的线程。
然而,如果你不小心,这将导致p^2
的线程数(因为每个原始的p
线程将产生另一个p
线程)。因此,默认情况下,嵌套是禁用的。
在如下情况下:
#pragma omp parallel
{
#pragma omp for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
}
当您违反OpenMP标准时,会触发未定义的行为。更准确地说,你违反了第2.5节(工作共享结构)中的限制:
a . 39.c和A.40.1c的例子清楚地说明了这一点:以下限制适用于工作共享结构:
- 每个工作共享区域必须被团队中的所有线程遇到,或者根本没有线程遇到。
- 对于团队中的每个线程,遇到的工作共享区域和屏障区域的顺序必须相同。
示例a . 39.c :下面的循环构造嵌套的示例符合,因为内部和外部循环区域绑定到不同的并行区域:
void work(int i, int j) {}
void good_nesting(int n)
{
int i, j;
#pragma omp parallel default(shared)
{
#pragma omp for
for (i=0; i<n; i++) {
#pragma omp parallel shared(i, n)
{
#pragma omp for
for (j=0; j < n; j++)
work(i, j);
}
}
}
}
示例A.40.1c:以下示例不符合,因为内环和外环区域紧密嵌套
void work(int i, int j) {}
void wrong1(int n)
{
#pragma omp parallel default(shared)
{
int i, j;
#pragma omp for
for (i=0; i<n; i++) {
/* incorrect nesting of loop regions */
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
}
}
注意这与:
不同#pragma omp parallel for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp parallel for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
,尝试在其中生成嵌套的并行区域。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 使用OpenMP获得完整、无损坏的输出需要什么
- 对于openMP来说,有什么建议可以将以下代码与openMP并行
- 什么是C/C++中的神奇函数(关于OpenMP)
- OpenMP 中的"static"和"dynamic"计划有什么区别?
- 当杂注内部有编译指示时,OpenMP 中会发生什么?
- OpenMP线程多于工作对性能的影响是什么?
- 在c++中,最快的方法是什么(使用OpenMP)
- 私有子句中的变量和OpenMP中并行区域中定义的变量之间有什么区别吗?
- 什么时候应该使用OpenMP库