【问题标题】:Difference between static and dynamic schedule in OpenMP in CC中OpenMP中静态和动态调度的区别
【发布时间】:2011-05-14 17:59:12
【问题描述】:

我有两个类似的代码。

第一

#pragma omp parallel for shared(g) private(i) schedule(dynamic, 1)
for(i = (*g).actualNumberOfChromosomes; i < (*g).maxNumberOfChromosomes; i++)
{
    AddCrossoverChromosome(g, i); // it doesnt change actualNumberOfChromosomes
    #pragma omp atomic
    (*g).actualNumberOfChromosomes++;
}

第二

#pragma omp parallel for shared(g) private(i) schedule(static, 1)
for(i = (*g).actualNumberOfChromosomes; i < (*g).maxNumberOfChromosomes; i++)
{
    AddCrossoverChromosome(g, i); // it doesnt change actualNumberOfChromosomes
    #pragma omp atomic
    (*g).actualNumberOfChromosomes++;
}

唯一的区别在于第一行。第一个代码工作正常,但第二个代码崩溃。为什么?

问题出在actualNumberOfChromosomes 的某个地方,但我想了解原因,而不仅仅是解决这个问题。我可以通过创建附加变量p 并为其分配actualNumberOfChromosomes 并更改循环以使i 等于p 来解决此问题。

【问题讨论】:

  • 能否详细说明第二个程序崩溃的原因?指针 g 是否已损坏?而且,它什么时候坠毁?你可以打印 i 的值。我需要更多信息来理解这个问题。您可以为每次迭代和每个线程打印出一些变量。

标签: c openmp


【解决方案1】:

问题在于此代码不兼容 OpenMP,并且不兼容的程序具有“未指定”行为。如果您查看 OpenMP API V3.0 规范,第 2.5.1 节循环构造,在它的描述下:

每个关联循环的迭代计数在进入最外层之前计算 环形。如果任何关联循环的执行更改了用于计算的任何值 任何迭代计数,则行为未指定。

静态调度类型和动态调度类型之间的最大区别在于,对于静态,可以在编译期间对块进行一定程度的计算和调度到线程,而对于动态,它是在运行时完成的(需要更多锁定)。

【讨论】:

    【解决方案2】:

    static 调度类型和 dynamic 调度类型之间的区别在于,static 可以预先计算块并决定如何在编译期间安排到线程,而dynamic 在运行时完成同样的事情。

    dynamic的使用涉及到一些复杂的机制,如死锁处理机制、负载处理等。

    您可以通过以下方式获取更多信息:http://openmp.blogspot.com

    【讨论】:

      猜你喜欢
      • 2012-06-06
      • 2021-03-18
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 2015-08-15
      • 2015-12-13
      • 2013-12-28
      相关资源
      最近更新 更多