3

我正在努力调整一个程序以使用 OpenMP。我有一组嵌套的 for 循环。最外面的 for 循环是沿着图像向下的 y 轴循环。我想在循环上运行多个并行线程,但我无法让它快速运行。

目前,当我运行 8 个线程时,它的运行方式如下:

thread 0 -> row 0,8,16...
thread 1 -> row 1,9,17...
thread 2 -> row 2,10,18...
thread 3 -> row 3,11,19...

我希望它以块的形式运行,以便线程 0 执行前 1/8 行。做这个的最好方式是什么?

当前代码:

...
int y_percent = data_size_Y/8;
int thread = 0;

#pragma omp parallel for num_threads(8) firstprivate(vecs, bufferedOut,data_size_X, data_size_Y, kern_cent_X, kern_cent_Y, sum)
for(int y = y_percent*omp_get_thread_num(); y < (omp_get_thread_num()+1)*y_percent; y++){ // the y coordinate of theoutput location we're focusing on     
4

2 回答 2

6

您可以使用schedulepragma 语句中的子句来指定您希望每个线程处理的块大小。在下面的示例中,我指定了static调度方法,其chunk大小指定了每个线程应获得的连续迭代次数。在这个简单的示例中,每个线程将获得每个 8 次迭代的块(例如,线程 0 将获得迭代 0-7,线程 1 将获得迭代 8-15,等等)。值得指出的是,如果您不关心块分布的顺序(例如,如果您不关心线程 0 是否获得第一个块),您可以替换staticdynamic. dynamic提供了在线程需要时将块分配给线程的能力,而不是从一开始就将块预先分配给线程(当某些迭代比其他迭代花费更长的时间时,这对于负载平衡很有用)。有关调度方法的更多信息,请查看以下内容:

例子:

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>

int main() {
  int i;
  int iterations = 32;
  int num_threads = 4;

#pragma omp parallel for schedule(static, 8) num_threads(num_threads)
  for(i=0; i<iterations; i++) {
    printf("thread %d: %d\n", omp_get_thread_num(), i);
  }

}
于 2013-11-03T15:47:13.363 回答
1

您可以简单地使用以下代码来实现这一点。

#pragma omp parallel for num_threads(8)
for(int y = 0; y < data_size_Y; y++) {
    ....
}

一般来说,我认为长长的列表firstprivate是没有必要的。根据您如何准确使用这些变量,它们中的大多数应该能够定义为shared.

于 2013-11-03T05:11:00.860 回答