【问题标题】:OpenMP parallelizationOpenMP 并行化
【发布时间】:2015-08-10 21:27:30
【问题描述】:

我正在编写一个具有科学目的的 C++ 程序。 该程序运行良好,并且返回了良好的结果,因此我决定使用 OpenMP 提高其性能。我要优化的循环如下:

        //== #pragma omp parallel for private(i,j)
        for (k=0; k < number; k++)
        {

        for (i=0; i < L; i++)
        {       
                for (j=0; j < L; j++)
                {       
                        red[i][j] = UNDEFINED;
                }
        }


        Point inicial =  {L/2, L/2, OCCUPIED};
        red[L/2][L/2] = OCCUPIED;
        addToList(inicial, red, list, L,f); 
        oc.push_back(inicial); 

        while (list.size() > 0 && L > 0)
        {       
                punto = selectPoint(red, list, generator, prob, p); 

                if (punto.state == OCCUPIED)
                {       
                        addToList(punto, red, list, L,f);

                        oc.push_back(punto);
                }    
                else
                {
                        out.push_back(punto);
                }


        }

        L = auxL; 

        oc.clear();
        out.clear();
        list.clear();

        }

 f = f*1.0/(number*1.0);

        if (f > 0.5)
        {
                inta = inta;
                intb = p;
                p = (inta + intb) / 2.0;
        }
        else if (f < 0.5)
        {
                intb = intb;
                inta = p;
                p = (inta + intb) / 2.0;
        }

        cout << p << endl;


        }

上面评论了我对 OpenMP 的尝试。如您所见,我已将 ij 声明为私有,因为它们是在并行部分之前声明的。我还尝试将L 设为私有,但没有任何结果。到处都是分段错误和坏指针。 我认为问题在于 while 循环嵌套在里面。我的问题是:omp parallel for 在这种情况下是否正确?还是我应该尝试只优化那个while循环? std::vector 是否会干扰 OpenMP?

注意:listocoutstd::vector&lt;Point&gt;Point 是一个具有三个 int 属性的简单结构。 addToList 是一个内部没有循环的函数。

【问题讨论】:

    标签: c++ openmp scientific-computing


    【解决方案1】:

    您可能需要阅读 OpenMP 教程。当您查看 OpenMP 代码时,您需要想象并行会发生什么。采取

    oc.push_back(inicial); 
    

    两个线程可以同时尝试这样做吗?是的。 std::vector 是否支持并行性?没有。

    上面的代码中充满了这些东西。


    如果您想在 OpenMP ode 中使用数据结构,您需要 to use locks。根据我个人的经验,当这种情况发生时,重构算法要比实际使用它们要好得多。虽然 OpenMP + 锁定是可能的,但这通常表明该想法存在问题(= 可能是主观观点)。

    【讨论】:

    【解决方案2】:

    当前答案指出了代码中的并发性,但请注意,并非所有数据结构都必须使用锁来实现线程安全。还有lock-free 数据结构。对于这种特殊情况,我们可以使用 Harris 无锁链表:https://timharris.uk/papers/2001-disc.pdf

    虽然我知道此时向 OP 指出并发问题非常有帮助,但我想确保我们不会通过说锁对于实现线程安全是绝对必要的来传达错误信息。

    【讨论】:

      【解决方案3】:

      指令#pragma omp parallel 定义了一段可以由不同线程同时执行的代码。在您的情况下,由于您没有指定任何进一步的指令,您的并行区域将由每个线程执行一次。为了实现并行行为,您可以尝试将循环分解为较小的任务(taskloop 指令将完成这项工作)。这些任务将保留在任务池中,直到线程开始执行它们。这样,您的循环将被您的线程分段并执行,而不是让每个线程执行整个循环。

      https://www.openmp.org/spec-html/5.0/openmpsu47.html 这是 taskloop 指令的官方 openMP 文档。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-08
        • 2015-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多