OpenMP Fortran做循环线程分配

时间:2019-01-28 07:09:46

标签: multithreading fortran openmp

假设我有一个索引为0..n-1的数组。有没有办法选择每个线程将处理哪些单元格?例如线程0将处理单元格0和5,线程1将处理单元格1和6,依此类推。

当前,每个线程操作的单元的选择不是由我决定的,而是系统选择的。我想得到那个控制权。

1 个答案:

答案 0 :(得分:1)

使用带有默认参数的!$OMP PARALLEL DO时,工作将在线程之间平均共享。如果您有10个线程和1000次迭代,则线程0将在1..100上运行,线程1将在101..200上运行,依此类推。

如果您想要更好的控件,请不要使用PARALLEL DO。仅使用将在所有线程中运行相同代码的$! OMP PARALLEL。在您的代码调用OMP_get_thread_num中,它将返回当前线程的ID。然后,您可以测试该值并将其分配给线程i,以进行所需的任何工作。例如,您可以计算该线程应处理的单元格范围。给出线程总数的OMP_get_num_threads也很有用。

例如,对于静态计划,C中omp parallel for个元素上的n绝对等于

#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
  }
}

对于fortran中的OMP PARALLEL DO来说是相同的(但是我对C语法有更好的了解)。如果要处理给定线程上的特定元素,则可以在给定线程中要考虑的索引范围上进行更复杂的计算。因此,如果您要处理每个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,依此类推。 Fortran翻译应该很简单。