При использовании !$OMP PARALLEL DO
с параметром по умолчанию работа будет равномерно распределена между вашими потоками.Если у вас есть, скажем, 10 потоков и 1000 итераций, поток 0 будет работать на 1..100, поток 1 на 101..200 и т. Д.
Если вы хотите более тонкий элемент управления, не используйтеPARALLEL DO
.Используйте только $! OMP PARALLEL
, который будет запускать один и тот же код во всех ваших потоках.В вашем коде вызовите OMP_get_thread_num
, который вернет идентификатор текущего потока.Затем вы можете проверить это значение и выделить потоку i
любую работу, какую захотите.Например, вы можете вычислить диапазон ячеек, которые должны обрабатываться этим потоком.OMP_get_num_threads
, который дает общее количество потоков, также может быть полезным.
Например, для статического расписания, omp parallel for
на n
элементах в C абсолютно эквивалентно
#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++){
// whatever
}
}
Он идентичен для OMP PARALLEL DO
на фортране (но я лучше знаю синтаксис Си).Если вы хотите обработать определенные элементы в данном потоке, вы можете иметь более сложные вычисления в диапазоне индексов, которые вы хотите рассмотреть в данном потоке.Поэтому, если вы хотите обработать каждый элемент num_threads
(в вашем примере 5), вы можете сделать:
#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){
// whatever
}
}
Если num_threads
= 5, поток 0 обработает элементы 0, 5, ..., резьба 1, элементы 1, 6 и т. д.Перевод на фортран должен быть простым.