我是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数组,然后将它们相加。我通过这种方式得到了一些改进,但成本非常高,我希望有更好的方法。
谢谢!