任务中的 OpenMP 任务循环

OpenMP taskloop inside task

我在 task 结构中使用 OpenMP taskloop 结构:

double compute(int input) {
  int array[4] = {0};
  double value = input;

  #pragma omp taskloop private(value)
  for(int i=0; i<5000000; i++) {                                                                                                       
    // random computation, the result is not meaningful
    value *= std::tgamma(std::exp(std::cos(std::sin(value)*std::cos(value))));
    int tid = omp_get_thread_num();
    array[tid] ++;
  }

  for(int i=0; i<4; i++) {
    printf("array[%d] = %d ", i, array[i]);
  }
  printf("\n");

  return value;
}

int main (int argc, char *argv[]) {
  omp_set_nested(1);
  omp_set_num_threads(4);  // 4 cores on my machine

  #pragma omp parallel 
  {
    #pragma omp single
    {
      #pragma omp task
      { compute(omp_get_thread_num()); }
    }
  }                                                                                                     
 }

结果数组全为0。但是,如果我将taskloop更改为parallel for

  #pragma omp parallel for private(value)
  for(int i=0; i<5000000; i++) {
    value *= std::tgamma(std::exp(std::cos(std::sin(value)*std::cos(value))));
    int tid = omp_get_thread_num();
    array[tid] ++; 
  }

那么数组的结果就是每个索引1250000。我使用 taskloop 结构有什么问题吗?

好吧,经@Cimbali 确认,您的问题似乎是数组未在线程之间共享。由于您没有明确说明变量数组是共享的还是私有的,OpenMP 将根据其规则来确定它。与parallel for相比,Tasks有一个特殊的数据共享属性。我找不到任何明确指定规则的内容。 This 是我能找到的最好的。尝试指定默认子句并共享数组变量。

根据Data-Sharing Attribute Rules,这是预期的行为:

"在任务生成构造中,如果没有 default 子句,则数据共享属性未由上述规则确定的变量是 firstprivate."

顺便说一句:始终建议使用 default(none),您将被迫明确定义数据共享规则。