我正在创建基于C - determine if a number is prime的基本素数检查器,但使用的是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;
}
使用 -fopenmp 进行编译时,GCC版本4.7.2发生错误,声明{for循环invalid controlling predicate
。
看起来这个错误是由for循环中的j平方引起的。有没有办法解决这个问题,仍然可以从算法中获得所需的输出?
答案 0 :(得分:12)
return
,因为它会在大括号之前导致退出。
请注意以下定义:
从OpenMP V2.5规范,1.2.2 OpenMP语言术语,p2:17 -
结构化块 - 对于C / C ++,可能是一个可执行语句 化合物,顶部有一个入口,顶部有一个出口 底部。
结构化块以打开的{
开头,以结束}
结束。 return
包含在这些大括号中,因此该程序也违反了结构化块的OpenMP定义,因为它有两个出口(一个在return
,一个在出口处通过大括号)
OpenMP对可以线程化的循环放置以下五个限制:
<
,<=
,>
的形式,
或>=
loop_invariant_integer <
或<=
,则循环变量必须
每次迭代都会递增,反之,如果进行比较
操作是>
或>=
,循环变量必须减少每一个
迭代。答案 1 :(得分:4)
根据OpenMP标准(§2.5.1,p.40),for
循环的控制谓词的可接受形式是:
您对j * j <= value
的使用明显违反了此要求。其基本原理是它需要编译器在运行时发出计算value
的整数平方根的代码,后者对于value
的某些值是未定义的,特别是对于负值。
您可以将j * j <= value
替换为j <= sqrt_value
,其中sqrt_value
是value
的整数平方根,但是会出现问题,因为在{{1}}中有另一个退出路径循环内部的结构化块。遗憾的是,在这种情况下不存在简单的解决方案,因为OpenMP不支持过早终止并行循环。