初学者在OpenMP -问题在循环

Beginner in OpenMP - Problems in cicle

本文关键字:循环 问题 OpenMP 初学者      更新时间:2023-10-16

我是OpenMP的初学者,我正试图并行化以下函数:

void calc(double *x, int *l[N], int d[N], double *z){
    #pragma omp parallel for
    for(int i=0; i<N; i++){
        double tmp = d[i]>0 ? ((double) z[i] / d[i]) : ((double) z[i] / N);
        for(int j=0; j<d[i]; j++)
            x[l[i][j]] += tmp;
    }
}

但是对于N=100000的线程,顺序时间大约是50秒,对于2个或更多的线程,它会上升到几分钟。

指针的L数组随机有1到30个元素(由d数组中的相应位置给出),元素在0到N之间变化,所以我知道我有负载平衡问题,但如果我有一个引导或动态调度(甚至自动)时间甚至更糟。

我也知道,问题显然是在访问x数组,因为它不是连续加入,但有一种方法来解决这个问题,并有某种加速在这个函数?

提前感谢!

假设您可以使用一些额外的空间来这样做,您可能可以加快此速度。

基本思想是为每个线程创建一个单独的和数组,然后当它们全部完成时,将这些单独副本中的相应元素相加,最后将结果的每个元素添加到原始x的相应元素中。

只要x相当小,这可能是相当合理的。如果x可能真的很大,它可能会很快变得不那么实用。考虑到L显然只有大约30个元素,听起来x可能也限制在大约30个元素(无论如何,在运行此代码时实际上也可以使用)。如果这是正确的,那么为每个线程拥有一个单独的副本应该不会造成重大问题。