OpenMP 并行计算循环索引

OpenMP parallel calculating for loop indices

我的并行编程 class 下面的程序演示了如何使用 OpenMP 中的并行构造来计算要在 for 循环中使用的每个线程的数组边界。

#pragma omp parallel
{
  int id = omp_get_thread_num();
  int p = omp_get_num_threads();
  int start = (N * id) / p;
  int end = (N * (id + 1)) / p;
  if (id == p - 1) end = N;
  for (i = start; i < end; i++)
  {
    A[i] = x * B[i];
  }
}

我的问题是,if 语句 (id == p - 1) 是否必要?根据我的理解,如果 id = p - 1,那么 end 已经是 N,因此 if 语句不是必需的。我在 class 的问答板上提问,但未能得到我理解的正确答案。假设是:N 是数组的大小,x 只是一个 int,id 在 0 和 p - 1 之间。

你说得对。实际上,(N * ((p - 1) + 1)) / p 相当于 (N * p) / p 假设 p 严格正数 (这是因为 OpenMP 线程数保证至少为 1)。 (N * p) / p 等同于 N 假设没有 溢出 。当整数除法导致某些截断时,这种情况通常很有用,但这里不是这种情况(像 (N / p) * id 这样的情况)。

请注意,此代码对于大 N 不是很安全,因为 sizeof(int) 通常为 4,乘法可能会导致溢出(导致 未定义的行为).在超级计算机节点等具有许多内核的机器上尤其如此。最好使用 size_t 类型,它通常是无符号的 64 位类型,意味着能够表示任何对象的大小(例如数组的大小)。