OpenMP 正确声明变量

OpenMP properly declaring variables

本文关键字:变量 声明 OpenMP      更新时间:2023-10-16

我是OpenMP和并行化的新手,所以虽然这个问题可能很简单,但我不确定是什么原因造成的,也不确定如何搜索解决方案。我的代码是:

int FindPrime(int size) {
    long long next_p = 2;
    #pragma omp parallel 
        shared(next_p,size)
    long long tid = omp_get_thread_num();
    long long tnum = omp_get_num_threads();
    for(int long long i = tid; i < size; i=i+tnum) {
        long long j;
        j=next_p+1;
         while (!IsPrime(j)) {
            j++;
        }
        next_p = j;
    }
    return next_p;
}

还有一个 main 函数调用 FindPrimeisPrime 检查一个数字是否是素数。

当我尝试使用 g++ 和标志-fopenmp-lpthread编译此代码时,我得到结果

error: 'tid' was not declared in this scope

指向线条

for(int long long i = tid; i < size; i=i+tnum){

对我来说也很奇怪,它只抱怨tid,而不是tnum,这也来自 OpenMP 函数。

您面临的问题来自您编写的parallel指令的范围。由于您没有使用 {} 来创建定义其范围的块,因此此块显然仅限于其后面的单行,即

long long tid = omp_get_thread_num();

因此,您的 tid 变量现在只有一行的作用域(其声明),因此当您想在 for 循环中使用它时不会声明。

要解决此问题,您只需添加{}来标记并行块,如下所示:

int FindPrime(int size) {
    long long next_p = 2;
    #pragma omp parallel shared(next_p,size)
    { // start of the parallel block
        long long tid = omp_get_thread_num();
        long long tnum = omp_get_num_threads();
        for(long long i = tid; i < size; i=i+tnum) {
            long long j;
            j=next_p+1;
            while (!IsPrime(j)) {
                j++;
            }
            next_p = j;
        }
    } // end of the parallel block
    return next_p;
}

这样,您的代码将并行化。但是,我不确定它应该做什么,但我很确定它没有按照您的期望去做......实际上,线程之间的next_p更新存在争用条件。我相信你应该重新考虑你的算法。

最后,您并行化for循环的方式与使用 #pragma omp for schedule( static, 1 ) 完全相同。如果您想坚持这种方法,您可能应该考虑使用它。