OpenMP For - 用于缓存优化的组循环

时间:2013-11-03 02:09:39

标签: c multithreading openmp

我正在努力调整程序以使用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     

2 个答案:

答案 0 :(得分:6)

您可以使用pragma语句中的schedule子句指定希望每个线程处理的块大小。在下面的示例中,我指定static调度方法,其大小为chunk,指定每个线程应获得的连续迭代次数。在这个简单的例子中,每个线程将获得每个8次迭代的块(例如,线程0将获得迭代0-7,线程1迭代8-15等)。值得指出的是,如果您不关心块分布的排序(例如,如果您不关心线程0是否获得第一个块),则可以将static替换为dynamic }。 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);
  }

}

答案 1 :(得分:1)

您只需使用以下代码即可实现此目的。

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

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