带有threadprivate向量的openMP C++错误


#include<iostream>
#include<vector>
#include<ctime>
#include<cmath>
#include<omp.h>
#include<array>
using namespace std;
double counter = 0;
vector<int> vec;
vector<double> reduction;
#pragma omp threadprivate(reduction)

vector<double> eet;
int fish;

void mario( int current_node, int current_depth) {
int q = current_node % 4;
#pragma omp simd
for( int i = 3 ; i < current_node; i+=4){
reduction[i]+=4;
mario(i, current_depth);
mario(i - 1,current_depth);
mario(i - 2,current_depth);
mario(i - 3,current_depth);
}
#pragma omp simd
for(int x = 1; x <= q; x++){
reduction[0]++;
mario(current_node - x,current_depth);
}
#pragma omp task firstprivate(current_node,current_depth)
{
if(current_depth > 0){
int new_depth = current_depth - 1;
#pragma omp simd
for(int i = current_node;i <= vec[current_node];i++){
reduction[i]++;
mario(i + 1,new_depth);
}
} 
} 
}

int main() {
omp_proc_bind_true;
omp_set_dynamic(0);
int nodes;
int timesteps;
int threadz;
cout << "enter number of nodes" << endl;
cin >> nodes;
cout << "enter number of timesteps" << endl;
cin >> timesteps;
cout << "enter number threads" << endl;
cin >> threadz;
omp_set_num_threads(threadz);
int mushroom = nodes - 2;
fish = nodes - 1;
vec.assign( nodes, mushroom );
clock_t t = clock();
vector<double> zed(mushroom + 1 , 0 );
eet = zed;
reduction = eet;
#pragma omp parallel copyin(reduction)
{
#pragma omp single
{
mario(nodes - 1, timesteps - 1);
}
#pragma omp critical
{
#pragma omp simd
for(int x = 0; x < zed.size();x++){
eet[x] += reduction[x];
}
}
#pragma omp barrier
}
for(int j = 0; j < eet.size(); j++){
counter += eet[j];
}
t = clock() - t;
double time_taken = ((double)t) / CLOCKS_PER_SEC;
cout << "mario took " << fixed << counter << " steps" << endl;
cout << "It took him " << time_taken << " seconds" << endl;
return 0;
}

在我的代码中,我声明向量归约:vector<double> reduction;

然后我立即使用threadprivate:#pragma omp threadprivate(reduction),但当我编译代码时,我会收到错误。

错误:首次使用后,"reduction"声明为"threadprivate">

13 |#pragma omp threadprivate(减少(

错误:对于"copyin","reduction"必须是"threadprivate">

82 |#pragma omp并行复制(减少(

是什么导致了这些错误?我只是声明了变量,没有做任何其他操作。

这个错误可以避免吗?

有没有其他方法可以减少递归函数的openMP任务

或解决问题的替代方法?

我编写代码的方式是否存在根本性的问题?

我正在使用gcc 9.3

,很抱歉,如果我的问题不清楚,请提出改进建议。

一个只适用于gcc的解决方案的主体,不幸的是,它只是一个变通方法,而不是一个合适的解决方案。

#include<iostream>
#include<vector>
#include<ctime>
#include<cmath>
#include<omp.h>
#include<array>
#include<thread>
using namespace std;
double counter = 0;
vector<int> vec;
thread_local vector<double> reduction;
vector<double> eet;
int fish;

void mario( int current_node, int current_depth) {
int q = current_node % 4;
#pragma omp simd
for( int i = 3 ; i < current_node; i+=4){
reduction[i]+=4;
mario(i, current_depth);
mario(i - 1,current_depth);
mario(i - 2,current_depth);
mario(i - 3,current_depth);
}
#pragma omp simd
for(int x = 1; x <= q; x++){
reduction[0]++;
mario(current_node - x,current_depth);
}
#pragma omp task firstprivate(current_node,current_depth)
{
if(current_depth > 0){
int new_depth = current_depth - 1;
#pragma omp simd
for(int i = current_node;i <= vec[current_node];i++){
reduction[i]++;
mario(i + 1,new_depth);
}
} 
} 
}

int main() {
omp_proc_bind_true;
omp_set_dynamic(0);
int nodes;
int timesteps;
int threadz;
cout << "enter number of nodes" << endl;
cin >> nodes;
cout << "enter number of timesteps" << endl;
cin >> timesteps;
cout << "enter number threads" << endl;
cin >> threadz;
omp_set_num_threads(threadz);
int mushroom = nodes - 2;
fish = nodes - 1;
vec.assign( nodes, mushroom );
clock_t t = clock();
vector<double> zed(mushroom + 1 , 0 );
eet = zed;
#pragma omp parallel
{
reduction = zed;
#pragma omp barrier
#pragma omp single
{
mario(nodes - 1, timesteps - 1);
}
#pragma omp critical
{
for(int x = 0; x < reduction.size();x++){
eet[x] += reduction[x];
}
}
#pragma omp barrier
}
for(int j = 0; j < eet.size(); j++){
counter += eet[j];
}
t = clock() - t;
double time_taken = ((double)t) / CLOCKS_PER_SEC;
cout << "mario took " << fixed << counter << " steps" << endl;
cout << "It took him " << time_taken << " seconds" << endl;
return 0;
}

这是一个糟糕的方法,显然gcc的c++实现使用了POSIX线程,而openMP的gcc实现只是后台的POSIX。来源:与其他并行库一起使用C++11 thread_local

因此,对于gcc,如果一个变量以这种方式发送给线程本地存储,它相当于openMP的"threadprivate"变量。

请其他人提出适当的解决方案。

最新更新