openmp - 使用锁定进行二维数组求和

时间:2016-11-08 16:38:29

标签: c++ parallel-processing synchronization openmp locks

我是openmp的新用户,我尝试并行化我的程序的一部分并使用锁定2维数组。我不会详细介绍我的实际问题,而是讨论以下简化示例:

假设我有一大群N>> 1粒子,它们的x,y位置存储在某些数据结构中。我想创建一个代表网格的二维计数器数组,并计算网格每个单元格中的所有粒子:

count [j] [k] + = 1(对于每个粒子的相应j,k,根据他的x,y值)

使用锁是一种自然的选择(2D阵列的规模为100x100及以上,因此当你拥有20核机器时,2个线程同时更新数组元素的可能性仍然很低)。代码的相关部分:

//定义一个2d锁:

omp_lock_t **count_lock;
count_lock = new omp_lock_t* [J+1];
for(j=0;j<=J;j++) {
    count_lock[j]=new omp_lock_t[K+1];
    memset(count_lock[j],0,(K+1)*sizeof(omp_lock_t));
}   

//初始化:

for(j=0;j<=J;j++) 
    for(k=0;k<=K;k++){
        omp_init_lock(&(count_lock[j][k]));
        omp_unset_lock(&(count_lock[j][k]));
    }

//使用锁定(确定正确的j,k之后):

omp_set_lock(&(count_lock[j][k]));
count[j][k] += 1;
omp_unset_lock(&(count_lock[j][k]));

//销毁锁:

for(i=0;i<=J;i++) 
    for(j=0;j<=K;j++)
        omp_destroy_lock(&(count_lock[i][j]));

for (j=0; j<=J; j++)
    delete[] count_lock[j];

delete[] count_lock;

将颗粒分成500个颗粒的组。每个组都是一个粒子链表,所有粒子组也形成一个链表。并行化来自于并行化遍历粒子组的“for”循环。

出于某种原因,我似乎无法做到正确......没有获得性能上的改进,并且经过几次迭代后模拟卡住了。

我尝试使用“原子”但它的性能比串行代码更差。我尝试的另一个选项是为每个线程创建一个私有2D数组,然后将它们相加。我通过这种方式得到了一些改进,但成本非常高,我希望有更好的方法。

谢谢!

0 个答案:

没有答案