代码之家  ›  专栏  ›  技术社区  ›  Richard

openacc调度

  •  0
  • Richard  · 技术社区  · 6 年前

    假设我有一个这样的构造:

    for(int i=0;i<5000;i++){
      const int upper_bound = f(i);
      #pragma acc parallel loop
      for(int j=0;j<upper_bound;j++){
        //Do work...
      }
    }
    

    在哪里? f 是单调递减函数 i .

    自从 num_gangs , num_workers vector_length 如果没有设置,openacc会选择它认为合适的调度。

    但是,它每次重新选择这样的调度是否遇到了Prima,还是只有一次遇到PROBMA?

    查看的输出 PGI_ACC_TIME 建议只执行一次调度。

    2 回复  |  直到 6 年前
        1
  •  1
  •   jefflarkin    6 年前

    pgi编译器将选择如何在编译时分解工作,但通常会在运行时确定帮派的数量。帮派本质上是可伸缩的并行性,因此决定多少可以推迟到运行时。向量的长度和工作线程的数量影响底层内核的生成方式,因此通常在编译时选择它们以最大化优化机会。在这样的循环中,如果在编译时边界不是很清楚,编译器必须在内核中生成一些额外的代码,以确保执行正确的迭代次数。

        2
  •  0
  •   Ruyk    6 年前

    根据OpenACC 2.6规范[1]第1357和1358行:

    与不具有SEQ子句的循环构造相关联的循环必须被写入,使得循环迭代计数在进入循环构造时是可计算的。

    似乎是这样,所以你的代码是有效的。

    然而,注意,它是定义了如何在帮派和工作者之间分配工作的实现,并且可能是PGI编译器只是简单地执行迭代的一些简单划分。 您可以手动地使用多语言和多语言定义帮会/工人的值,并且传递给这些子句的整数表达式可以依赖于函数的值(参见规范中的)。

    〔1〕 https://www.openacc.org/sites/default/files/inline-files/OpenACC.2.6.final.pdf