Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

correct use of interal function and openmp

Tags:

c++

loops

openmp

i have a for loop which calls an internal function :

some variables
for(int i=0; i< 10000000; i++)
    func(variables)

Basically, func gets a reference to some array A, and inserts values in A[i] - so i'm assured that each call to func actually tries to insert a value to a different place in A, and all other input variables stay the the same as they were before the for loop. So func is thread-safe.

Can i safely change the code to

some variables
#pragma omp parallel for
for(int i=0; i< 10000000; i++)
    func(variables)

From what i understand from the openmp tutorials, this isn't good enough - since the openmp libraries wouldn't know that the variables given to func are really thread-safe, and so this would yield attempts to perform synchronization which would slow things up, and i would need to declare variables private, etc. But actually, when trying the code above, it seems to work indeed faster and parallel - is this as expected? I just wanted to make sure i'm not missing something.

The declaration of func :

 func(int i, int client_num, const vector<int>& vec)
like image 695
dan12345 Avatar asked Nov 02 '11 15:11

dan12345


2 Answers

First of all, OpenMP cannot magically determine the dependency on your code. It is your responsibility that the code is correct for parallelization.

In order to safely parallelize the for loop, func must not have loop-carried flow dependences, or inter-iteration dependency, especially for read-after-write pattern. Also, you must check there are no static variables. (Actually, it's much more complex to write down the conditions of the safe parallelization in this short answer.)


Your description of func says that func will write a variable into a different place. If so, you can safely parallelize by putting pragma omp parallel for, unless the other computations do not dependences that prohibit parallelization.

Your prototype of func: func(int i, int client_num, const vector<int>& vec)

There is a vector, but it's a constant, so vec should not have any dependency. Simultaneous reading from different threads are safe.

However, you say that the output is different. That means somethings were wrong. It's impossible to say what the problems are. Showing prototype of the function never helps; we need to know what kind of computations are done func.

Nonetheless, some steps for the diagnosis are:

  • Check the dependency in your code. You must not have dependences shown in the below. Note that the array A has loop-carried dependence that will prevent parallelization:

for (int k = 1; k <N; ++k) A[k] = A[k-1]+1;

  • Check func is re-entrant or thread-safe. Mostly, static and global variables may kill your code. If so, you can solve this problem by privatization. In OpenMP, you may declare these variables in private clause. Also, there is threadprivate pragma in OpenMP.
like image 119
minjang Avatar answered Sep 25 '22 14:09

minjang


You do not change anywhere your loop variable i, so it is no problem for the compiler to parallelize it. As i is only copied into your function, it cannot be changed outside.

The only thing you need to make sure is that you write inside your functions only to positions A[i] and read only from positions A[i]. Otherwise you might get race conditions.

like image 31
tune2fs Avatar answered Sep 23 '22 14:09

tune2fs