使用openmp更好

时间:2012-02-19 19:10:05

标签: c++ openmp

我正在尝试实现openMP,但就像我之前的许多其他海报一样,结果只是放慢了代码的速度。受到之前答案的启发,我从使用#pragma omp parallel for转到#pragma omp task,希望能避免一些开销。不幸的是,并行化代码仍然是串行代码的两倍。从其他答案来看,似乎正确的程序取决于代码的具体要求,这就是为什么我认为我必须自己提出问题。

首先是伪代码:

#pragma omp parallel
{
#pragma omp master
while (will be run some hundreds of millions of times)
{
    for (between 5 and 20 iterations)
    {
        #pragma omp task
        (something)
    }
    #pragma omp taskwait <- it is important that all the above tasks are completed before going on

    (something)

    if (something)
    {
        (something)

        for (between 50 and 200 iterations)
        {
            #pragma omp task 
            (something)
        }
        #pragma omp taskwait

        (something)
    }

}
}

只有两个for循环可以并行化,其余的必须以正确的顺序完成。我提出将并行和主指令放在while循环之外,以减少创建团队的开销。

我也有点好奇我是否正确使用taskwait - 规范声明“父任务”被搁置直到所有子任务都被执行,但不清楚这个术语是否也适用于此,任务区域没有嵌套的地方。

任何人都可以想出一个更好的使用openMP的方式,这样我才能真正加速吗?

编辑:while循环中的每个步骤都取决于之前的所有步骤,因此必须按顺序完成,最后更新。如果有人想知道的话,它是用于模拟神经网络的“事件驱动算法”的实现。

3 个答案:

答案 0 :(得分:2)

对于并行编程,您还应该以一种很少需要同步线程的方式设计问题。每次同步线程时,您将获得所有线程的最差性能。如果您需要同步线程,请尝试重新设计问题,以避免这些同步。

将代码从#pragma omp parallel for调整为#pragma omp task将无法获得任何重大改进,因为他们的执行时间差异通常可以忽略不计。在尝试调整一些例程调用或omp语句之前,您需要调整问题以适应并行执行。您需要真正考虑“并行”才能获得良好且可扩展的性能提升,只需调整序列代码即可。

在你的代码中,你应该尝试并行化while循环而不是内部for循环。如果你将小for循环平行化,你将不会获得任何显着的性能提升。

答案 1 :(得分:0)

我不确定任务是否是正确的方式。我不熟悉任务,但似乎每次遇到#pragma omp task时都会启动一个线程。我宁愿尝试类似的东西:

while (will be run some hundreds of millions of time)
{
#pragma omp parallel
{
    for (between 5 and 20 iterations)
    {
        (something) 
    }
#pragma omp single/master
{

    (something)
    bool flag = false;
    if (something)
    {
        (something)
        flag = true;
    }
}

    if (flag)
    {
        for (between 50 and 200 iterations)
        {
            (something)
        }
    }
#pragma omp single/master
{
            (something)
}
    }
    }

同样重要的是要记住,对于并行执行,for循环中的任务可能很小,以提供任何加速,因为启动和同步线程会产生开销。您还应该考虑重写程序的可能性,这样您就不需要同步线程了,您现在做了很多。我的猜测是你的算法和工作负载实际上对于并行执行来说很小,因为它现在就可以提供任何加速。

答案 2 :(得分:0)

你还记得相应地设置你的环境变量吗? OMP_NUM_THREADS = N,其中N是处理器支持的线程数或核心数