OpenMP Fortran делает назначение потока цикла - PullRequest
0 голосов
/ 28 января 2019

Предположим, у меня есть массив с индексами 0..n-1.Есть ли способ выбрать, какие ячейки будет обрабатывать каждый поток?Напримернить 0 будет обрабатывать ячейки 0 и 5, нить 1 будет обрабатывать ячейки 1 и 6 и т. д.

В настоящее время выбор ячеек, с которыми работает каждый поток, решается не мной, а системой.Я хотел бы получить этот контроль.

1 Ответ

0 голосов
/ 28 января 2019

При использовании !$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 и т. д.Перевод на фортран должен быть простым.

...