我正在尝试并行化基于粒子模拟的代码,并且遇到基于OpenMP的方法性能较差的问题。我的意思是:用于粒子模拟的并行化OpenMP代码的性能不佳
- 使用Linux工具
top
显示CPU使用率,运行CPU的OpenMP线程的平均使用率为50%。 - 随着线程数量的增加,加速收敛到约1.6倍。收敛速度非常快,即使用2个线程可以达到1.5的加速。
以下伪码说明了所有并行区域的基本模板。注意,在单个时间步骤中,正在执行以下所示方式的5个平行区域。基本上,作用在粒子上的力是相邻粒子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分配私人副本吗?
这是*大量的数据*预先存储,或者你从过程中的文件中读取它? I/O将永远在那里摧毁人们的期望\ =正如您所说的,多次访问同一个空间可能会导致抖动,因此设置一些访问策略将会很好 – Rubens
谢谢。我不需要从文件中读取它。它们在运行时生成并存储在物理RAM中。 –
NN(i)是如何均匀分布的?负载不平衡可能是一个问题吗?您可以尝试不同的时间表以供循环查看。否则,您需要使用分析器来查明您的时间花在哪里;我非常喜欢[scalasca](http://www.scalasca.org)来解决OpenMP性能问题。 –