OpenMP 不允许使用 != 操作
在多线程并行计算时,openmp是很好的选择。
但是使用错误的操作符,可能会出现一些编译错误。
比如,编译以下代码:
#pragma omp parallel shared (j){
#pragma omp for schedule(dynamic)
for(i = 0; i != j; i++){
// do something
}
}
或
vector<int>query;
#pragma omp parallel shared (j){
#pragma omp for schedule(dynamic)
for(auto it = query.begin(); i != query.end(); i++){
// do something
}
}
会出现下面的错误:
error: invalid controlling predicate.
for(auto it = query.begin(); i != query.end(); i++){
是因为:
OpenMP 不允许使用 != 操作。
只允许:> < >= <=
为什么不能进行 “!=” 操作?
原因1:
** 对于signed int 类型,编译器可能不知道循环次;导致出现无限循环。**
1.比如这样是被允许的:
for( i = 0; i < n; ++i )
如果n>=0; 编译器可以决定执行n次循环;
如果n<0;执行0次循环;
但是,
for( i = 0; i != n; ++i )
同样,
如果n>=0,编译器应该能够确定有“n”次迭代;
如果n<0,我们不知道它有多少次迭代。
2.比如这样是被允许的:
for( i = 0; i < n; i += 2 )
如果n>=0,编译器应该能够确定有“(n+1)/2”次迭代;
如果n<0,0次迭代。
但是,
for( i = 0; i != n; i += 2 )
编译器无法确定“i”是否会命中“n”。
如果“n”是奇数,则会产生无限循环。
3.比如这样是被允许的:
for( i = 0; i < n; i += k )
如果n>=0,编译器可以生成代码来计算行程计数为floor((n+k-1)/k),
如果n<0,则为0,因为编译器知道循环必须向上计数;
在这种情况下,如果k<0,则它不是合法的OpenMP程序。
但是:
for( i = 0; i != n; i += k )
编译器甚至不知道是在向上还是向下计数。
它不知道“i”是否会击中“n”。
它可能是一个无限循环。
原因2:
OpenMP不允许提前终止线程组。
使用==或!=,OpenMP无法确定循环何时停止。
1.一个或多个线程可能达到终止条件,这可能不是唯一的。
2.OpenMP无法关闭可能永远检测不到这种情况的其他线程。