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

发布于 2024-10-03 02:24:47 字数 845 浏览 2 评论 0原文

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

#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 & 4.5.0 并且它们都按预期工作,但对于 MS 2010,我看到上述行为,其中 29 次迭代分配给线程 0,一次迭代分配给线程 1。

真的很奇怪:它花了我很多时间稍微意识到这可能只是一个调度问题。我用谷歌搜索并找到了这个网站,如果您跳到底部,其中有一个示例,其中必须自动生成输出。所有使用动态引导调度的迭代都被分配给线程零???!?

任何指导将不胜感激!

Direct Question: I've got a simple loop with, what can be, a computationally intensive function. Let's assume that each iteration takes the same amount of time (so load balancing should be easy).

#pragma omp parallel
{

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

}  // parallel block

Why are all of the iterations assigned to a single thread? I can add a:

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

and it prints a bunch of zeros with only the last iteration assigned to thread 1.

My System: I must support cross compiling. So I'm using gcc 4.4.3 & 4.5.0 and they both work as expected, but for MS 2010, I see the above behavior where 29 iterations are assigned to thread 0 and one iteration is assigned to thread 1.

Really Odd: It took me a bit to realize that this might simply be a scheduling problem. I google'd and found this website, which if you skip to the bottom has an example with what must be auto-generated output. All iterations using dynamic and guided scheduling are assigned to thread zero??!?

Any guidance would be greatly appreciated!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别靠近我心 2024-10-10 02:24:47

最有可能的是,这是因为 Visual Studio 中的 OMP 实现决定您所做的工作远不足以值得将其放在多个线程上。如果您只是增加迭代次数,那么您很可能会发现其他线程的利用率更高。动态调度意味着实现仅在需要时才派生新线程,因此,如果不需要它们,则不会使它们工作或分配它们工作。

Most likely, this is because the OMP implementation in Visual Studio decided that you did nowhere near enough work to merit putting it on more than one thread. If you simply increase the quantity of iterations, then you may well find that the other threads have more utilization. Dynamic scheduling means that the implementation only forks new threads if it needs them, so if it doesn't need them, it doesn't make them or assign them work.

简美 2024-10-10 02:24:47
  1. 如果每次迭代花费相同的时间,那么您实际上不需要动态调度,动态调度会比静态调度策略产生更多的调度开销。 (static, 1) 和 (static) 应该没问题。

  2. 你能让我知道每次迭代的长度吗?关于你引用的例子(MSDN的调度示例),是因为每次迭代的工作量很小,所以第一个线程刚刚完成了差不多的工作。如果你真的增加每次迭代的工作量(至少一个毫秒的数量级),那么你就会看到差异。

我做了很多与OpenMP调度策略相关的实验。 MSVC 的动态调度实现效果很好。我很确定您在每次迭代中的工作量太小。

  1. If each iteration takes the same amount of time, then you actually don't need a dynamic scheduling which causes more scheduling overhead than static scheduling policies. (static, 1) and (static) should be okay.

  2. Could you let me know the length of each iteration? Regarding the example you cited (MSDN's example for schedulings), it is because the amount of work of each iteration is so small, so the first thread just got almost work. If you really increase the work of each iteration (at least an order of millisecond), then you will see the differences.

I did a lot of experiments related to OpenMP scheduling policies. MSVC's implementation of dynamic scheduling works well. I'm pretty sure your work in each iteration was too small.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文