【问题标题】:Optimization with Loop Tiling and OpenMP使用循环平铺和 OpenMP 进行优化
【发布时间】:2019-10-15 17:15:31
【问题描述】:

下面是我尝试使用 OpenMP 和循环平铺(又名循环阻塞)优化的功能。但是,在我应用下面的循环平铺后,我的 out 输出当前给出了错误的值。有人可以查看我的代码,并指出它出错的原因。非常感谢

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include "utils.h"
const long BLOCK_SIZE = 8*DIM;
int i, j, k,ii,jj,kk, dim = DIM-1;

long compute, out = 1.0, we_need, gimmie;

void work_it_par(long *old, long *new)
{
 we_need = need_func();
 gimmie = gimmie_func();

 #pragma omp parallel for private(i,j,k,ii,jj,kk, compute)      firstprivate(we_need, gimmie, dim,old,BLOCK_SIZE) reduction(+:out)   num_threads(omp_get_num_procs())
for (ii=1; ii<dim-BLOCK_SIZE; ii+=BLOCK_SIZE) {
  for (jj=1; jj<dim-BLOCK_SIZE; jj+=BLOCK_SIZE) {
    for (kk=1; kk<dim-BLOCK_SIZE; kk+=BLOCK_SIZE) {
      for (i=ii; i<ii+BLOCK_SIZE; i++) {
        for (j=jj; j<jj+BLOCK_SIZE; j++) {
          for (k=kk; k<kk+BLOCK_SIZE; k++) {
            //int temp = i*DIM*DIM+j*DIM+k;
            compute = old[i*DIM*DIM+j*DIM+k] * we_need;
            out += compute / gimmie;
          }
        }
      }

    }
  }
}

printf("AGGR:%ld\n",out);

}

【问题讨论】:

    标签: c optimization openmp


    【解决方案1】:

    首先,const long BLOCK_SIZE = 8*DIM; 对我来说似乎很可疑... 也许用/ 替换* 会更符合您的要求?

    但即便如此,您仍然必须通过检查 ijk 索引是否超出其限制来处理限制。我让你弄清楚如何实现这一目标。

    算法的最后一点:你确定你的循环必须从索引 1 开始吗?

    最后,关于 OpenMP 正确性的几点说明:

    • 虽然我看不出有什么问题,但声明firstprivate(we_need, gimmie, dim,old,BLOCK_SIZE) 并没有多大意义。这些可以愉快地留下shared
    • 我真的不知道num_threads(omp_get_num_procs()) 是否正确。我的感觉是它确实是有效的,但只是为了“安全”,我倾向于将函数调用与指令分开(通过首先调用函数并将其结果存储在一个常量中,然后在指令中使用它) ,或在parallel 指令之前调用omp_set_num_threads()
    • 当您的算法固定后,您可能需要考虑添加一些 collapse 指令来提高您在此处实现的并行度...

    祝你的代码好运。

    【讨论】:

    • num_threads(omp_get_num_procs()) 不是必需的,无论如何它都是默认的。如果不存在 num_threads 子句或线程数通过环境或 API 发生变化,OpenMP 通常会使用所有可用的内核(尽管这是实现定义的)。
    • @MichaelKlemm 我同意将线程数设置为可用处理核心的最大值在大多数情况下默认设置是多余的(尽管它是实现定义的),也许不是这样可能是有原因的。因此,强制它阻止用户随后使用OMP_NUM_THREADS 进行调整可能是一个坏主意。但我的观点更多的是关于在编译时指令中调用运行时函数:我认为(希望)它是有效的,但我仍然更喜欢避免它以防万一......
    • 您可以(几乎)在采用表达式的 OpenMP 子句中使用任意代码。 OpenMP 定义了何时计算这些表达式。像往常一样:权力越大,责任越大。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多