When using a !$OMP PARALLEL DO
with default parameter, work will be evenly shared among your threads. If you have, say, 10 threads and 1000 iterations, thread 0 will work on 1..100, thread 1 on 101..200 and so on.
If you want a finer control, do not use a PARALLEL DO
. Use just a $! OMP PARALLEL
that will run the same code in all your threads. In your code call OMP_get_thread_num
that will return the id of the current thread. Then you can test this value and allocate to thread i
whatever work you want. You can for instance compute a range of cells that should processed by this thread. OMP_get_num_threads
that gives the total number of threads can also be useful.
For instance, for a static schedule, a omp parallel for
on n
elements in C is absolutely equivalent to
#pragma omp parallel
{
int id_thread=omp_get_thread_num();
int num_threads=omp_get_num_threads();
int min_index=id_thread*(n/num_threads);
int max_index=min((id_thread+1)*(n/num_threads),n)-1;
for(int i=min_index; i<= max_index; i++){
}
}
It is identical for a OMP PARALLEL DO
in fortran (but I have a better knowledge of C syntax). If you want to process specific elements on a given thread, you can have more complex computations on the index range you want to consider in a given thread. So if you want to process every num_threads
element (5 in you example), you can do:
#pragma omp parallel
{
int id_thread=omp_get_thread_num();
int num_threads=omp_get_num_threads();
for(int i=id_thread; i<n; i+=num_threads){
}
}
If num_threads
=5, thread 0 will process elements 0, 5,..., thread 1 elements 1, 6, and so on. Fortran translation should be straighforward.