c++ 我可以使用临时二维数组来避免OpenMP中的数据依赖性吗?

vulvrdjw  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(112)

我有这样一段代码:

int n=5;
Eigen::VectorXd vec(n);
vec.setZero();
for(int i=0;i<100;i++)
{
    int idx = i%n;
    vec(idx)+=(i/n);
}
std::cout<<vec<<endl;

我想把它并行化。
我想出了一个避免数据依赖的方法。

int n=5;
int num_thread = 6;
omp_set_num_threads(num_thread);
Eigen::MatrixXd mat(num_thread,n);
mat.setZero();
#pragma omp parallel for
for(int i=0;i<100;i++)
{
    int idx_pool = omp_get_thread_num();
    int idx_col = i%n;
    mat(idx_pool,idx_col)+=(i/n);
}
Eigen::VectorXd vec(n);
vec = mat.rowwise().sum();
std::cout<<vec<<endl;

我在想,这是不是一种方法?

jgovgodb

jgovgodb1#

假设您的真实的代码在并行循环中具有更高的工作负载,那么这是一种非常有效的方法(如果工作负载较低,并行化本身可能就没有意义)。最先进的方法是使用约简(如@VictorEijkhout所述),但如果您必须定义一个自定义变量,则会很麻烦(并且根据情况没有明显的性能改善)。除了在一些特定的情况下,我不认为内存问题是真实的的问题:当使用归约时,无论如何,线程具有被归约的变量/数组的隐藏私有副本。

fcy6dtqo

fcy6dtqo2#

您已经解决了争用条件问题,但却成倍增加了程序的内存需求。您还引入了一个非并行操作:rowwise().sum(),这会降低性能增益。
因为你在做一种归约,你可以使用OpenMP的reduction子句,如果+运算符被重载了,对于VectorXd类,是吗?否则你可以自己定义。

相关问题