我正在尝试并行化用于基于粒子的模拟的代码,并且遇到基于 OpenMP 的方法的性能不佳。我的意思是:
- 使用 Linux 工具显示 CPU 使用率
top
,运行 CPU 的 OpenMP 线程的平均使用率为 50%。 - 随着线程数量的增加,加速收敛到大约 1.6 倍。收敛速度非常快,即我使用 2 个线程达到了 1.5 的加速。
以下伪代码说明了实现的所有并行区域的基本模板。请注意,在单个时间步中,正在执行以下所示方式的 5 个并行区域。基本上,作用在粒子上的力i < N
是相邻粒子的几个场特性的函数j < NN(i)
。
omp_set_num_threads(ncpu);
#pragma omp parallel shared( quite_a_large_amount_of_readonly_data, force )
{
int i,j,N,NN;
#pragma omp for
for( i=0; i<N; i++ ){ // Looping over all particles
for ( j=0; j<NN(i); j++ ){ // Nested loop over all neighbors of i
// No communtions between threads, atomic regions,
// barriers whatsoever.
force[i] += function(j);
}
}
}
我正在尝试找出观察到的瓶颈的原因。我最初的天真猜测是:
如前所述,线程之间共享大量内存以进行只读访问。不同的线程很有可能同时尝试读取相同的内存位置。这会造成瓶颈吗?我应该让 OpenMP 分配私有副本吗?