我是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数组时因为它没有被连续加入但是有没有办法解决这个问题并且在这个函数中有某种加速?
提前致谢!
答案 0 :(得分:1)
假设你可以花费一些额外的空间来做这件事,你可以加快速度。
基本思想是为每个线程创建一个单独的和数组,然后当它们全部完成时,在这些单独的副本中添加相应的元素,最后将该结果的每个元素添加到相应的元素中。原x
。
只要x
相当小,这可能是非常合理的。如果x
可能真的很大,那么匆忙可能会变得不那么实用。鉴于L
显然只有大约30个元素,听起来x
可能仅限于大约30个元素(无论如何,在运行此代码时实际上都可以使用)。如果这是正确的,那么为每个线程单独复制不应该导致重大问题。