OpenMP并行化

时间:2015-05-28 11:34:16

标签: c++ openmp scientific-computing

我正在编写一个具有科学目的的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<Point>Point是一个包含三个int属性的简单结构。 addToList是一个内部没有循环的函数。

3 个答案:

答案 0 :(得分:3)

您可能想要阅读OpenMP教程。当您查看OpenMP代码时,您需要想象并行发生的事情。取

oc.push_back(inicial); 

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

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

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

答案 1 :(得分:1)

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

虽然我知道向OP指出并发问题在这一点上有很大的帮助,但我想确保我们不会传达错误的信息,说锁是获得线程安全所必需的。

答案 2 :(得分:0)

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

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