Parallel processing 为什么openmp在某些机器上的并行化速度较慢

Parallel processing 为什么openmp在某些机器上的并行化速度较慢,parallel-processing,openmp,Parallel Processing,Openmp,我正在开发一个数值模拟,可以并行运行以提高速度。我通常多次运行模拟,然后对单个结果进行平均。此循环,即多次运行,使用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(dynami

我正在开发一个数值模拟,可以并行运行以提高速度。我通常多次运行模拟,然后对单个结果进行平均。此循环,即多次运行,使用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
        }
    }
正如您所看到的,并行计算要比序列化计算慢得多,即使是在总体上。我确信这不是内存问题,计算机有多个内核


可能是什么问题?它可能是openmp实现吗?或者系统中有什么配置错误?我真的不知道该找什么。

看来缓存一致性是个问题。如果
total
是您的共享数组,并且每个线程在
total
中更新自己的单元格,因为线程正在动态拾取工作,所以很可能线程必须更新
total
中可能位于同一缓存线中的相邻值


在您的测试机器上,这不太可能造成太大的伤害,因为在共享的L3中,
total
可能是一致的,但在集群中,它需要在网络上来回移动,这应该会造成伤害。

由于我没有足够的声誉,我将此添加为一个答案,而不是一个注释:

您是否已确保对不同模拟的数据进行了并行而非串行初始化

我知道这会根据您的体系结构产生巨大的差异。也许你可以给出一个关于架构的提示

准确地说: 如果你这样做

for(i = 1; i < prms.number_runs; ++i)
   allocAndInitializeSimulationData( i )

#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
    }
}
for(i=1;i对于(iRun=1;iRun实际上,我看到的是,real、user和sys的集群实现报告的时间比测试机上相应的值要高。当你使用办公室墙上的时钟时,你会得到什么计时?或者,更重要的是,如果你在st向时钟例程插入调用,你会得到什么计时程序的艺术和结束?两次运行都在同一台机器上,我只设置了一次-P标志,使程序并行运行。第二次运行的时间确实更长。例如,在我的笔记本电脑上,第二次运行的时间大约为25秒或30秒,是第一次运行的两倍……你的模拟是否执行了大量的I/O操作?你的线程是否协同工作在并行运行过程中,从一个内核到另一个内核的非同步跳转?您的计算是否涉及随机数生成(这可以解释为什么需要多次运行)?如果是,如何生成所有这些数字?(根据您的操作方式,可能存在隐藏的共享变量)。您确定这两台机器上的随机数生成库是相同的吗?您能为所有线程使用不同的RNG实例(使用
gsl\u RNG\u alloc
)并重新计时以查看是否有更改吗?我已解决了问题,如我的问题评论中所述。无论如何,谢谢。
for(i = 1; i < prms.number_runs; ++i)
   allocAndInitializeSimulationData( i )

#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
    }
}
#pragma omp parallel if(prms.parallel) shared(total) private(iRun)
{
   #pragma omp for schedule(dynamic)
   for(i = 1; i < prms.number_runs; ++i)
      initializeAndAllocSimulation( i )

   #pragma omp for schedule(dynamic)
   for (iRun = 1; iRun <= prms.number_runs; iRun++)
   {
      // perform the simulation
   }
}