【问题标题】:openMP excessive synchronizationopenMP 过度同步
【发布时间】:2017-08-18 11:40:24
【问题描述】:

我正在尝试将 openMP 并行化添加到一个相当大的项目中,但我发现 openMP 在并行块之外并行块之外进行了太多同步。

这种同步是针对所有变量完成的,即使是那些未在并行块中使用的变量,它也是连续完成的,不仅在进入块之前。

我举了一个例子来证明这一点:

#include <cmath>

int main()
{
    double dummy1 = 1.234;

    int const size = 1000000;
    int const size1 = 2500;
    int const size2 = 500;

    for(unsigned int i=0; i<size; ++i){

        //for (unsigned int j=0; j<size1; j++){
        //  dummy1 = pow(dummy1/2 + 1, 1.5);
        //}

        #pragma omp parallel for
        for (unsigned int j=0; j<size2; j++){
            double dummy2 = 2.345;
            dummy2 = pow(dummy2/2 + 1, 1.5);
        }
    }
}

如果我运行此代码(注释了 for 循环),运行时间为 6.75 秒(带并行化)和 30.6 秒(不带并行化)。太好了。

但是如果我取消注释 for 循环并再次运行它,过度同步就会启动,我得到的结果是 67.9s 并行化和 73s 没有并行化。如果我增加 size1,我什至会得到比没有它的并行化更慢的结果。

有没有办法禁用此同步并仅在第二个 for 循环之前强制它?或者任何其他方式如何提高速度?

请注意,在实际示例中,外部循环都不是第一个 for 循环。外层实际上是一个 ODE 求解器,而第一个内层是更新内部值的负载。

我正在使用 gcc (SUSE Linux) 4.8.5

感谢您的回答。

【问题讨论】:

  • 这个问题没什么意义。您是说在 OpenMP 之外添加工作会增加执行时间。这很令人惊讶吗?如果您运行代码时将您的虚拟循环注释掉,而您的 OpenMP 循环完全注释掉,您会发现第一个循环需要时间!您似乎已经得出了一个结论(OpenMP 正在做一些它没有做的事情)没有任何证据!
  • 这段代码正确吗? dummy1 似乎没有在并行循环中使用。另外,您是否独立地为第一个和第二个循环计时?可能是第一个循环需要很长时间来处理,以至于并行化对第二个循环的影响在一起测量时并不明显。
  • @Tudor 这段代码不应该做任何可用的事情,它只是一个例子。
  • @JimCownie:我认为测量的数字很清楚:如果我们只看没有并行化的结果,我们会得到第二个 for 循环需要 30.6 秒,第一个循环需要 73-30.6 = 42.4 秒。至于并行化的结果,第二个循环需要 6.75 秒,而第一个循环需要 67.9-6.75 = 61.15 秒。现在我希望您看到,增加的工作不仅是由 for 循环本身造成的,而且还有一些额外的东西——由 openMP 引起的。我希望我说得更清楚。
  • @David Sery:这可能是因为您在两个循环中使用了相同的变量名。您是否尝试在第一个循环中将 j 更改为其他内容?

标签: c++ performance optimization parallel-processing openmp


【解决方案1】:

最后,我的问题的解决方案是指定线程数 = 处理器内核数。似乎超线程导致了问题。所以使用(我的处理器有 4 个真正的核心)

#pragma omp parallel for num_threads(4)

没有第一个 for 循环我得到 8.7s 的时间和 51.9s 的时间。仍然有大约 1.2 秒的开销,但这是可以接受的。使用默认(8 个线程)

#pragma omp parallel for

时间是 6.65s 和 68s。这里的开销大约是 19 秒。

因此,如果没有其他代码存在,超线程会有所帮助,但当它存在时,使用它可能并不总是一个好主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-20
    • 2012-11-07
    • 2013-04-12
    • 2019-08-27
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    相关资源
    最近更新 更多