内循环的有效并行化

时间:2018-10-27 07:56:56

标签: c++ for-loop openmp pragma

我有以下顺序代码:

for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  // Inner body
  }
}

我的目标是简单地并行化内部循环。可以这样完成:

for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
  #pragma omp parallel for
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  // Inner body
  }
}

此代码的问题是,在外循环的每次运行中都会产生新线程。为了加快此代码的速度,我想提前创建一个线程组并多次使用它们。我发现为此目的有一条指令#pragma omp for

#pragma omp parallel
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
  #pragma omp for
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  // Inner body
  }
}

但是,如果我正确理解指令#pragma omp parallel的用法,则会导致外循环运行多次。这是正确的吗?

修改: 这里是一个更详细的示例:

// Let say that the image is represented as an array of pixels
// where pixels is just one integer.
std::vector<Image> images = getImages();

for (auto & image : images) { // Loop over all images
  #pragma omp parallel for
  for (unsigned j = 0; j < image.size(); ++j) { // Loop over each pixel
    image.at(j) += addMagicConstant(j);      
  }
}

目标:我想生成一组线程,然后重复使用它们仅并行化内部循环(=​​遍历图像像素)。

2 个答案:

答案 0 :(得分:0)

您的代码完全有效,并且确实可以正常工作:

#pragma omp parallel
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
  #pragma omp for
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  // Inner body
  }
}

#pragma omp parallel将产生线程。然后,每个线程将继续通过外部循环。在每次循环迭代时,线程将到达#pragma omp for,并且内部循环将在线程之间分布。每个omp for块的末尾都有一个隐式屏障,因此线程将等到内部循环完成后再进行下一个外部循环迭代。

如果可以确保所有线程都进入循环,则可以在另一个for或while循环中或在条件部分中具有omp for分布式循环。

但是禁止使用诸如:

#pragma omp parallel
for (unsigned ii= 0; ii< omp_thread_num(); ++ii) { // Number of iteration of outer loop depends on the thread
// Outer body
  #pragma omp for
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  // Inner body
  }
}

#pragma omp parallel
if(condition_depending_on_thread_num) { 
  #pragma omp for
  for (unsigned j = 0; j < maxSize; ++j) { // Loop
  // Inner body
  }
}

答案 1 :(得分:-1)

您尝试过吗:

#pragma omp parallel for
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
  for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
  }
}