【发布时间】:2012-04-12 14:19:09
【问题描述】:
我正在开发一个可以并行运行以提高速度的数值模拟。我通常多次运行模拟,然后对各个结果进行平均。这个循环,多次运行,使用 openmp 并行化:
// set the number of threads
omp_set_num_threads (prms.nthreads);
#pragma omp parallel if(prms.parallel) shared(total) private(iRun)
{
#pragma omp for schedule(dynamic)
for (iRun = 1; iRun <= prms.number_runs; iRun++)
{
// perform the simulation
}
}
实际上没有共享变量,除了total,它是一个大小为iRun 的数组,其中每个元素保存相应运行的结果。到目前为止,在我测试的所有机器上,速度都与内核数量成正比;所以使用 4 个线程比没有并行化快 4 倍。但是,在我们的计算集群上,情况并非如此(第二次运行是并行化并使用 2 个线程,因此速度应该是原来的两倍):
$ time hop ...
real 0m50.595s
user 0m50.484s
sys 0m0.088s
$ time hop ... -P
real 1m35.505s
user 3m9.238s
sys 0m0.134s
如您所见,并行计算比串行计算慢得多,即使总体而言也是如此。我确信这不是内存问题,并且计算机具有多个内核。
可能是什么问题?可能是openmp实现吗?还是系统中的某些内容配置错误?我真的不知道要找什么。
【问题讨论】:
-
实际上,我看到的是您的集群实现 real、user 和 sys 报告的时间高于测试机器上的相应值。当你使用办公室墙上的时钟时,你会得到什么时间?或者,也许更重要的是,如果你在程序的开始和结束处插入对时钟例程的调用,你会得到什么时间?
-
两次运行都在同一台机器上,我只设置了一次 -P 标志,使程序并行运行。第二次运行真的/感觉更长。例如,在我的笔记本电脑上,第二次运行大约需要 25 或 30 秒,比第一次快两倍……
-
您的模拟是否执行大量 I/O 操作?在并行运行期间,您的线程是否不断地从一个内核跳到另一个内核?您的计算是否涉及随机数生成(这可以解释为什么您需要多次运行它)?如果是这样,您如何生成所有这些数字? (取决于你如何做事,可能有一个隐藏的共享变量)。
-
你确定两台机器上的随机数生成库是一样的吗?
-
您能否为所有线程使用不同的 RNG 实例(使用
gsl_rng_alloc)并重做您的计时以查看是否有变化?
标签: parallel-processing openmp