【问题标题】:omp barriers are blocking欧普障碍正在阻挡
【发布时间】:2015-08-23 14:39:59
【问题描述】:

我有一个代码:

#include <stdio.h>
#include <omp.h>

static void func()
{
    char t[30];
    sprintf(t,"%d %d\n",omp_get_num_threads(),omp_get_thread_num());
    write(1,t,strlen(t));
    write(1,"checkpoint 1\n",13);
    #pragma omp barrier 
    write(1,"checkpoint 2\n",13);
    #pragma omp barrier
    write(1,"checkpoint 3\n",13);
    #pragma omp barrier
    write(1,"checkpoint 4\n",13);
}

int main()
{
    int i;
#pragma omp parallel for
    for(i=0;i<2;i++)
    {
       func();
    }
} 

和输出:

8 1
8 0
checkpoint 1
checkpoint 1
checkpoint 2
checkpoint 2
[here my program blocks].

如果我将 for 中的 2 更改为 8,它会起作用。但我想在我的 for 循环中有 2 个。

如何在循环前不使用 omp_set_num_threads(2) 使我的代码正常工作? (当我放这个时它也有效)

【问题讨论】:

  • OpenMP 障碍在团队中的线程中是全局的。您不能只让 N 个线程中的两个在屏障上同步。这就是当您将线程数显式设置为两个时它起作用的原因。

标签: openmp barrier


【解决方案1】:

障碍用于同步团队中的所有线程。所有到达的线程都将被阻塞,直到所有线程都到达屏障。只有这样,他们才能继续。

因此,为了让您的程序终止,所有线程在其生命周期内必须达到相同数量的屏障。如果一个线程的障碍比其他线程多,则该线程永远无法通过其额外的障碍,因为它会等待其他线程 - 因为它们没有额外的障碍,所以它们永远不会到达那里。

您在函数func 中有一个障碍,它在您的并行循环的每次迭代中执行一次。由于由 OpenMP 将这些迭代分配给线程,因此并非所有这些迭代都可能收到相同数量的迭代(在您的情况下,它们确实收到相同数量的线程数 2 - 每个线程一次迭代,这就是您的程序的原因然后终止)。不等数量的障碍会阻止您的程序。

确保只在你知道所有线程都会同样频繁地执行它的地方设置屏障。

【讨论】:

  • 我认为这个答案不能正确解释问题中描述的行为。此答案中给出的原因将解释为什么程序在打印 checkpoint 1 两次后可能会阻塞。但是在这种情况下,程序会打印两次checkpoint 1,然后打印两次checkpoint 2,然后阻塞。打印出checkpoint 2 一定意味着所有线程都已经到达并通过了第一个屏障。看起来线程然后在第二个障碍处阻塞。奇怪。
  • P.S.:我想我应该补充一点,您的回答很好地解释了类似于问题中描述的障碍和问题。点赞。
  • @jcsahnwaldt 哇,你是对的,我没有注意这个事实。无论如何,我再次运行代码,它在 first 屏障处被阻塞。无论我多么努力地扭曲参数和时间,我都无法达到第二个。鉴于上面的代码,这确实是可以发生的唯一事情。所以我想发布的代码版本和输出版本之间只是不匹配。当人们试图让事情正常工作并不断修改代码时,这种情况经常发生。但感谢您指出!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 2017-10-01
  • 1970-01-01
  • 2015-07-28
  • 2011-10-16
相关资源
最近更新 更多