C++ 为什么使用OpenMP调度(动态)将循环中的所有迭代并行化给一个线程?(MSVS 2010)
直接问题:我有一个简单的循环,可以是计算密集型函数。让我们假设每个迭代花费相同的时间(因此负载平衡应该很容易)C++ 为什么使用OpenMP调度(动态)将循环中的所有迭代并行化给一个线程?(MSVS 2010),c++,visual-studio-2010,scheduling,openmp,C++,Visual Studio 2010,Scheduling,Openmp,直接问题:我有一个简单的循环,可以是计算密集型函数。让我们假设每个迭代花费相同的时间(因此负载平衡应该很容易) #pragma omp并行 { #计划的pragma omp(动态) 对于(int i=0;i
#pragma omp并行
{
#计划的pragma omp(动态)
对于(int i=0;i<30;i++)
{
MyExpensiveFunction();
}
}//并行块
为什么所有的迭代都分配给一个线程?我可以补充一点:
std::cout << "tID = " << omp_get_thread_num() << "\n\n";
std::cout最有可能的原因是,VisualStudio中的OMP实现决定您所做的工作远远不够,不值得将其放在多个线程上。如果您只是增加迭代的数量,那么您可能会发现其他线程的利用率更高。动态调度意味着实现只在需要时分叉新线程,因此如果不需要它们,就不会使它们工作或分配它们
如果每次迭代花费相同的时间,那么实际上不需要动态调度,因为动态调度比静态调度策略会导致更多的调度开销。(静态,1)和(静态)应该可以
你能告诉我每次迭代的长度吗?关于您引用的示例(MSDN的调度示例),这是因为每次迭代的工作量非常小,所以第一个线程几乎完成了工作。如果您真的增加了每次迭代的工作量(至少一毫秒),那么您将看到差异
我做了很多与OpenMP调度策略相关的实验。MSVC实现的动态调度运行良好。我非常确定您在每个迭代中的工作量都太小。我认为总体上您是正确的-因此我接受了您的答案,但我想补充一点,在经过广泛的测试后,我能够确定指出的奇怪行为实际上是由于将我的进程锁定到一组特定的内核。在Windows中,我使用的是SetProcessAffinityMask——我肯定有足够的内核来容纳我的线程(我在双四核上称为omp_set_max_threads(4)),但无论出于什么原因,这种亲和性都会扰乱OpenMP分配。当我删除关联(保留omp_set_max_threads(4))时,我看到了与gcc匹配的预期分配。@M.Tibbits:通常,您会在问题中提到这类事情:P
std::cout << "tID = " << omp_get_thread_num() << "\n\n";