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

我试图编译以下代码:

#pragma omp 并行共享(j){#pragma omp for schedule(动态)for(i = 0; i != j; i++){//做一点事}}

但我收到以下错误:错误:控制谓词无效.

OpenMP 标准指出对于 parallel for 构造函数它仅"允许以下操作符之一:<, <=, > >=.>

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


即使我制作 for(i = 0; i != 100; i++),虽然我可以把<"或<=".

解决方案

.

我向 OpenMP 开发人员发送了一封关于此主题的电子邮件,我得到了答复:

对于有符号整数,环绕行为是未定义的.如果我们允许 !=,程序员可能会得到意外的tripcount.问题是编译器是否可以生成代码来计算循环的行程计数.

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

for( i = 0; i 

编译器可以确定有'n'次迭代,如果n>=0,并且零次迭代如果n <0.

对于像这样的循环:

for( i = 0; i != n; ++i )

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

对于像这样的循环:

for( i = 0; i 

编译器可以生成代码来计算行程计数(循环迭代计数)为 floor((n+1)/2) if n >= 0 和 0 if n <0.

对于像这样的循环:

for( i = 0; i != n; i += 2 )

编译器无法确定i"是否会命中n".如果n"是奇数怎么办?

对于像这样的循环:

for( i = 0; i 

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

对于像这样的循环:

for( i = 0; i != n; i += k )

编译器甚至不知道我是在计数还是在计数.它不知道 'i' 是否会碰到 'n'.这可能是一个无限循环.

信用:OpenMP ARB

I was trying to compile the following code:

#pragma omp parallel shared (j)
{
   #pragma omp for schedule(dynamic)
   for(i = 0; i != j; i++)
   {
      // do something
   }
}

but I got the following error: error: invalid controlling predicate.

The OpenMP standard states that for parallel for constructor it "only" allows one of the following operators: <, <=, > >=.

I do not understand the rationale for not allowing i != j. I could understand, in the case of the static schedule, since the compiler needs to pre-compute the number of iterations assigned to each thread. But I can't understand why this limitation in such case for example. Any clues?


EDIT: even if I make for(i = 0; i != 100; i++), although I could just have put "<" or "<=" .

解决方案

.

I sent an email to OpenMP developers about this subject, the answer I got:

For signed int, the wrap around behavior is undefined. If we allow !=, programmers may get unexpected tripcount. The problem is whether the compiler can generate code to compute a trip count for the loop.

For a simple loop, like:

for( i = 0; i < n; ++i )

the compiler can determine that there are 'n' iterations, if n>=0, and zero iterations if n < 0.

For a loop like:

for( i = 0; i != n; ++i ) 

again, a compiler should be able to determine that there are 'n' iterations, if n >= 0; if n < 0, we don't know how many iterations it has.

For a loop like:

for( i = 0; i < n; i += 2 )

the compiler can generate code to compute the trip count (loop iteration count) as floor((n+1)/2) if n >= 0, and 0 if n < 0.

For a loop like:

for( i = 0; i != n; i += 2 )

the compiler can't determine whether 'i' will ever hit 'n'. What if 'n' is an odd number?

For a loop like:

for( i = 0; i < n; i += k )

the compiler can generate code to compute the trip count as floor((n+k-1)/k) if n >= 0, and 0 if n < 0, because the compiler knows that the loop must count up; in this case, if k < 0, it's not a legal OpenMP program.

For a loop like:

for( i = 0; i != n; i += k )

the compiler doesn't even know if i is counting up or down. It doesn't know if 'i' will ever hit 'n'. It may be an infinite loop.

Credits: OpenMP ARB

相关文章