为什么 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
相关文章