简体   繁体   中英

OpenMP parallelization

I'm writing a C++ program with scientific purposes. The program works well and it returns good results, so I decided to improve its perfomance using OpenMP. The loop I want to optimize is the following one:

        //== #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;


        }

My try with OpenMP is commented above. As you can see I've declared i and j as private because they're declared before the parallel section. I've also tried to make L private, with no results. Only segmentation faults and bad pointers everywhere. I think the problem is that while loop nested inside. My questions are: Is the omp parallel for correct in this case? or should I try to optimize only that while loop? Are the std::vector interfering with OpenMP?

NOTE: list , oc and out are std::vector<Point> , and Point is a simple struct with three int properties. addToList is a function with no loops inside.

You might want to go over an OpenMP tutorial. When you look at OpenMP code, you need to imagine what can happen in parallel. Take

oc.push_back(inicial); 

Can two threads try to do this at the same time? Yes. Does std::vector support parallelism? No.

The code above is full of these things.


If you want to use data-structures within your OpenMP ode, you need to use locks . From my personal experience, when this happens, it is far better to refactor the algorithm than actually use them. While OpenMP + locks is possible, it is usually an indication that there's a problem with the idea (= a possibly subjective view).

The current answer points out the concurrency in the code, but please note that not all data-structures have to be implemented with locks to attain thread-safety. There are also lock-free data structures. For this particular case, we could the Harris lock free linked list: https://timharris.uk/papers/2001-disc.pdf

While I know that pointing out concurrency issues to the OP is of great assistance at this point, I want to make sure we don't convey a wrong message by saying that locks are absolutely necessary to attain thread safety.

The directive #pragma omp parallel defines a piece of code that can be executed simultaneously by various threads. In your case, as you have not specified any further directive, your parallel region will be executed once by every thread. In order to achieve a parallel behavior you could try to break the loop into smaller tasks(the taskloop directive will do the job). Those tasks will remain in a task pool until a thread starts executing them. This way your loop will be fragmented and executed by your threads instead of making each thread execute the whole loop.

https://www.openmp.org/spec-html/5.0/openmpsu47.html here's the official openMP documentation for the taskloop directive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM