OpenMP与部分嵌套并行

时间:2015-02-11 01:51:34

标签: c multithreading parallel-processing openmp

我有以下情况:我有一个很大的外部for循环,基本上包含一个函数foo()。在foo()中,可以同时执行bar1()和bar2(),并且需要在bar1()和bar2()之后执行bar3()。我已经并行化了大外环,并且部分为bar1()和bar2()。我假设每个外部循环线程都会生成自己的节线程,这是正确的吗?

如果上面的假设是正确的,那么只有在执行bar1()和bar2()的线程完成后才能让bar3()执行?如果我使用critical,它将在所有线程上停止,包括外部for循环。如果我使用单曲,那么就不能保证bar1()和bar2()会完成。

如果上面的假设不正确,我如何强制外部循环线程重新使用bar1(),bar2()的线程,并且每次都不生成新线程?

请注意,temp是一个变量,其init和clear很昂贵,所以我在init循环外拉init并清除。它使问题更加复杂,因为bar1()和bar2()都需要某种临时变量。最理想的是,temp应该为每个创建的线程初始化和清除,但是我不确定如何强制为段生成的线程。 (没有section pragma,它在并行块中工作正常)。

main(){
    #pragma omp parallel private(temp)
    init(temp);
    #pragma omp for schedule(static)
    for (i=0;i<100000;i++) {
        foo(temp);
    }
    clear(temp);
}

foo() {
    init(x); init(y);
    #pragma omp sections
    {
        { bar1(x,temp); }
        #pragma omp section
        { bar2(y,temp); }
    }
    bar3(x,y,temp);
}

1 个答案:

答案 0 :(得分:1)

我认为简单地并行化for循环应该会给你足够的并行性来饱和CPU中的资源。但是如果你真的想并行运行两个函数,那么下面的代码就可以了。

main(){
    #pragma omp parallel private(temp) 
    {
        init(temp);
        #pragma omp for schedule(static)
        for (i=0;i<100000;i++) {
            foo(temp);
        }
        clear(temp);
    }
}

foo() {
    init(x); init(y);

    #pragma omp task
    bar1(x,temp);

    bar2(y,temp);

    #pragma omp taskwait

    bar3(x,y,temp);
}