我正在创建一个基本的素数检查器,基于C - 确定一个数字是否为素数 ,但是使用OpenMP.
int isPrime(int value)
{
omp_set_num_threads(4);
#pragma omp parallel for
for( int j = 2; j * j <= value; j++)
{
if ( value % j == 0) return 0;
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
使用-fopenmp进行编译时,GCC版本4.7.2 出错,说明invalid controlling predicatefor循环.
看起来这个错误是由for循环中的j平方引起的.有没有办法解决这个问题,仍然可以从算法中获得所需的输出?
0de*_*al0 14
return 在循环中是不允许的,因为它会在花括号之前导致退出.
请注意下面给出的定义:
从OpenMP V2.5规范,1.2.2 OpenMP语言术语,p2:17-
结构化块 - 对于C/C++,一个可执行语句,可能是复合语句,顶部有一个条目,底部有一个单独的出口.
结构化块从打开开始,以{结束结束}.该return被包含在这些大括号内,所以这个方案也违背了一个结构化块OpenMP的定义,因为它具有两个出口(一个在return与一个通过在支架的出口)
OpenMP对可以线程化的循环放置以下五个限制:
<,<=,>,或>=loop_invariant_integer<或<=,则循环变量必须在每次迭代时递增,相反,如果比较操作是>或>=,则循环变量必须在每次迭代时递减.根据OpenMP标准(第2.5.1节,第40页),for循环控制谓词的可接受形式为:
您对的使用j * j <= value明显违反了此要求。其基本原理是,它要求编译器value在运行时发出计算的整数平方根的代码,而对于的某些值value,尤其对于负数,则未定义后者。
您可以将替换j * j <= value为j <= sqrt_value,其中sqrt_value是的整数平方根value,但是这样会出现问题,即在循环内部的结构化块中具有备用退出路径。不幸的是,由于OpenMP不支持并行循环的过早终止,因此在这种情况下不存在简单的解决方案。