0

EDIT: changed the code and phrasing to make my doubt more explicit

I'm struggling to parallelize a loop in C using OpenMP for quite a while and want directions of how I should takle this challenge. the loop consists of the following (in case you wish to know this loop is the main loop integrated in a simulated annealing algorithm):

for(attempt = 0; attempt < SATISFIED; attempt++) {
    i = (rand() % (len-1)) + 1;
    j = i + (rand() % (len-i));

    if(...) {

        ...

        //Update global static variables:
        if(dst < best_distance)
            set_best(dst, path);

        //Stop this attempt:
        attempt   = -1;
    }

    //Decrease the temperature:
    temp = change_temp(temp);
}

The problem with this loop is that the number of iterations to do cannot be calculated by it's condition so I came up with a different way to write this loop in order to be able to use openmp:

while(keepGoing){
    keepGoing = 0;

    #pragma omp parallel for default(none) shared(len, best_distance, best_path, distances, avg_distance, path) private( i, j, seed, swp_dst) lastprivate(dst, temp, keepGoing) firstprivate(dst, temp, abort, keepGoing)
    for(attempt = 0; attempt < SATISFIED; attempt++) {

        #pragma omp flush (abort)
        if (!abort) {

            seed = omp_get_thread_num();
            i = (rand_r(&seed) % (len-1)) + 1;
            j = i + (rand_r(&seed) % (len-i));

            //Update progress:
            #pragma omp critical
            {

            if(...) {

                ...

                //Update global static variables:
                    if(dst < best_distance)
                        set_best(dst, path);

                //Stop this attempt:
                keepGoing = 1;
                abort     = 1;
                #pragma omp flush (abort)
                #pragma omp flush (keepGoing)

            }
            }

            //Decrease the temperature:
            temp = change_temp(temp);
        }
    } 
}

However this solution gives a different then the sequential version I wrote before output for reasons I don't understand... Are the openmp directives being well placed? Or should I use them in different ways? Thanks in advance for any answer.

sharp_c-tudent
  • 463
  • 5
  • 17
  • 1
    Check out [OpenMP cancellation](http://jakascorner.com/blog/2016/08/omp-cancel.html) or [practical alternatives](http://stackoverflow.com/a/40288632/620382). Also see [threadprivate randomness](https://stackoverflow.com/questions/4287531/how-to-generate-random-numbers-in-parallel) – Zulan Nov 03 '16 at 15:08
  • 1
    In general, please make sure your question contains sufficient information: What does *wrong result* mean? Provide a [mcve]? Which OpenMP version do you use? Why have you chosen to `default(shared)` - are you aware of the implications of making variables in a loop shared? – Zulan Nov 03 '16 at 15:09
  • @Zulan yes i know the consequences of making them shared (data races and such) but i also make some of them private so they are not all shared. I dont know my openmp verzion but that isnt important because i can upgrade it if i need to. The wrong result im talking about is that variables get a different value after the while then they would with the sequential version. But the values themselves are not important i just want help to parallelize a loop like: for(i=0;i – sharp_c-tudent Nov 03 '16 at 16:26
  • I just want some hints maybe. Perhaps if i should use taks or something like that – sharp_c-tudent Nov 03 '16 at 16:29
  • 1
    Well, what do you supposed the value of `i`, `j`, `swp_dst` is during an iteration if they are shared? How can you say the values are not important? Have you even checked the links I have provided? – Zulan Nov 03 '16 at 20:37
  • @Zulan oh I see I didn't know pseudorandomness worked the way it's shown on your link, it may very well be the problem here. I will try to change it and see. Thanks :) – sharp_c-tudent Nov 03 '16 at 23:14
  • @Zulan I followed every tip I could find on your links and updated my post with my new solution however there is still something not right because it still behaves different then the sequential version (global static variables end up with different values and it's not because of the randomization)... :(. I really can't understand what I'm doing wrong, if you notice something please let me know. – sharp_c-tudent Nov 04 '16 at 02:36
  • 1
    You must define the `seed` outside of the loop as described in the linked answer. Otherwise you get the same value every time. For the other stuff you must provide a [mcve] and a clearer problem statement - otherwise we can't help you. – Zulan Nov 04 '16 at 06:39

0 Answers0