OpenACC调度

时间:2018-06-19 18:02:39

标签: openacc pgi

说我有一个这样的结构:

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...
  }
}

fi的单调递减函数。

由于未设置num_gangsnum_workersvector_length,因此OpenACC选择它认为合适的计划。

但是,每次遇到实用程序时,还是仅在第一次遇到实用程序时,才重新选择这样的计划?

查看PGI_ACC_TIME的输出,表明调度仅执行一次。

2 个答案:

答案 0 :(得分:1)

PGI编译器将选择在编译时如何分解工作,但通常会在运行时确定组的数量。帮派本质上是可扩展的并行性,因此可以决定将多少个推迟到运行时。向量的长度和数量会影响底层内核的生成方式,因此通常在编译时选择它们,以最大限度地提高优化机会。对于像这样的循环,在编译时并没有真正知道边界,编译器必须在内核中生成一些额外的代码,以确保执行正确的迭代次数。

答案 1 :(得分:0)

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

  

必须编写与没有seq子句的循环构造相关联的循环,以便在进入循环构造时可以计算循环迭代计数。

似乎是这种情况,因此您的代码有效。

但是,请注意,实现定义了如何在帮派和工人之间分配工作,并且可能是PGI编译器只是在简单地对迭代进行分区。 您可以使用num_gangs和num_workers手动定义gang / workers的值,传递给这些子句的整数表达式可以取决于函数的值(请参见OpenACC规范的2.5.7和2.5.8)。

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