为什么使用给定一个线程的OpenMP调度(动态)并行化循环中的所有迭代? (MSVS 2010)

时间:2010-11-14 06:30:06

标签: c++ visual-studio-2010 scheduling openmp

直接问题:我有一个简单的循环,可能是一个计算密集型函数。让我们假设每次迭代花费相同的时间(因此负载平衡应该很容易)。

#pragma omp parallel
{

#pragma omp for schedule(dynamic)
for ( int i=0; i < 30; i++ )
{
     MyExpensiveFunction();
}

}  // parallel block

为什么所有迭代都分配给一个线程?我可以添加一个:

std::cout << "tID = " << omp_get_thread_num() << "\n\n";

并打印出一堆零,只有最后一次迭代分配给线程1。

我的系统:我必须支持交叉编译。所以我正在使用gcc 4.4.3&amp; 4.5.0并且它们都按预期工作,但对于MS 2010,我看到上面的行为,其中29次迭代被分配给线程0并且一次迭代被分配给线程1。

真的奇怪:我花了一点时间才意识到这可能只是一个调度问题。我google'd并找到this website,如果你跳到底部有一个示例,必须是自动生成输出。使用动态引导计划的所有迭代都会分配给线程零?? ??

非常感谢任何指导!!

2 个答案:

答案 0 :(得分:2)

最有可能的原因是,这是因为Visual Studio中的OMP实现决定您没有足够的工作来将它放在多个线程上。如果只是增加迭代次数,那么您可能会发现其他线程的利用率更高。动态调度意味着实现只在需要时才会分叉新线程,因此如果它不需要它们,它就不会生成它们或为它们分配工作。

答案 1 :(得分:1)

  1. 如果每次迭代花费相同的时间,那么实际上您不需要动态调度,这会导致比静态调度策略更多的调度开销。 (静态,1)和(静态)应该没问题。

  2. 你能告诉我每次迭代的长度吗?关于你引用的例子(MSDN的schedulings示例),这是因为每次迭代的工作量都很小,所以第一个线程几乎可以工作。如果你真的增加了每次迭代的工作量(至少一个毫秒级),那么你会看到差异。

  3. 我做了很多与OpenMP调度策略相关的实验。 MSVC的动态调度实现很有效。我很确定你在每次迭代中的工作都太小了。