首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么OpenMP不允许使用!=运算符?

为什么OpenMP不允许使用!=运算符?
EN

Stack Overflow用户
提问于 2012-11-10 01:08:15
回答 4查看 6.5K关注 0票数 78

我正在尝试编译以下代码:

代码语言:javascript
复制
#pragma omp parallel shared (j)
{
   #pragma omp for schedule(dynamic)
   for(i = 0; i != j; i++)
   {
      // do something
   }
}

但是我得到了以下错误:错误:无效的控制谓词

OpenMP standard声明对于parallel for构造函数,它“只”允许以下运算符之一:<<=> >=

我不明白为什么不允许使用i != j。对于static schedule,我可以理解,因为编译器需要预先计算分配给每个线程的迭代次数。但是我不能理解为什么在这种情况下会有这样的限制。有什么线索吗?

编辑:即使我创建了for(i = 0; i != 100; i++),也可以使用,尽管我可以只使用"<“或"<=”。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-16 02:14:15

我就这个问题给OpenMP开发人员发了一封电子邮件,得到的答案是:

对于带符号的int,换行行为是未定义的。如果我们允许!=,程序员可能会得到意想不到的tripcount。问题是编译器是否可以生成代码来计算循环的trip计数。

对于一个简单的循环,例如:

代码语言:javascript
复制
for( i = 0; i < n; ++i )

编译器可以确定有'n‘次迭代,如果是n>=0,则为,如果n< 0,则为零迭代。

对于像这样的循环:

代码语言:javascript
复制
for( i = 0; i != n; ++i ) 

同样,编译器应该能够确定有'n‘次迭代,如果n<0,,;如果n<0,,我们不知道它有多少次迭代。

对于像这样的循环:

代码语言:javascript
复制
for( i = 0; i < n; i += 2 )

编译器可以生成代码来计算跳跃计数(循环迭代计数),如果n >= 0,则为floor((n+1)/2),如果n< 0,则计算0

对于像这样的循环:

代码语言:javascript
复制
for( i = 0; i != n; i += 2 )

编译器无法确定'i‘是否会命中'n’。如果“n”是奇数怎么办?

对于像这样的循环:

代码语言:javascript
复制
for( i = 0; i < n; i += k )

编译器可以生成代码来计算floor((n+k-1)/k) if n >= 0和0 if n< 0,因为编译器知道循环必须向上计数;在这种情况下,如果k < 0,则它不是合法的OpenMP程序。

对于像这样的循环:

代码语言:javascript
复制
for( i = 0; i != n; i += k )

编译器甚至不知道我是在向上还是向下计数。它不知道'i‘是否会命中'n’。它可能是一个无限循环。

Credits:OpenMP ARB

票数 79
EN

Stack Overflow用户

发布于 2012-11-16 01:25:15

答案很简单。OpenMP不允许提前终止线程组。使用==或!=时,OpenMP无法确定循环何时停止。1.一个或多个线程可能会遇到终止条件,该条件可能不是唯一的。2. OpenMP没有办法关闭其他可能永远不会检测到这种情况的线程。

票数 5
EN

Stack Overflow用户

发布于 2012-11-10 02:10:03

如果我看到这份声明

代码语言:javascript
复制
for(i = 0; i != j; i++)

用来代替语句

代码语言:javascript
复制
for(i = 0; i < j; i++)

我会想知道为什么程序员会做出这样的选择,更不用说它可能意味着同样的事情。这可能是因为OpenMP在语法上做出了艰难的选择,以迫使代码具有一定的清晰度。

这里的代码对!=的使用提出了挑战,并可能有助于解释为什么它是不允许的。

代码语言:javascript
复制
#include <cstdio>

int main(){
    int j=10;
   #pragma omp parallel for
   for(int i = 0; i < j; i++){
    printf("%d\n",i++);
   }
}

请注意,在for语句和循环本身中,i都是递增的,这导致了无限循环的可能性(但不是保证)。

如果谓词为<,那么在并行上下文中仍然可以很好地定义循环的行为,而无需编译器在循环中检查i的更改并确定这些更改将如何影响循环的界限。

如果谓词为!=,则循环的行为不再是定义良好的,它的范围可能是无限的,从而防止了简单的并行细分。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13312679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档