假设我有一个这样的构造:
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选择了它认为合适的调度。
但是,它是在每次遇到语用时重新选择这样的调度,还是只在第一次遇到该语用时重新选择一次?
查看PGI_ACC_TIME的输出可以看出,调度只执行一次。
发布于 2018-08-09 20:09:23
PGI编译器将选择如何在编译时分解工作,但通常会在运行时确定帮派的数量。帮派本质上是可伸缩的并行性,所以决定有多少可以推迟到运行时。向量长度和工作人员的数量影响底层内核的生成方式,因此通常在编译时选择它们来最大化优化机会。对于这样的循环,在编译时并不真正知道边界,编译器必须在内核中生成一些额外的代码,以确保执行正确的迭代次数。
发布于 2018-06-20 21:00:02
根据OpenAcc 2.6 specification1 1357和1358号线:
必须编写与没有seq子句的循环构造关联的循环,以便在进入循环构造时循环迭代计数是可计算的。
似乎是这样的,所以您的代码是有效的。
但是,请注意,实现定义了如何在帮派和工作人员之间分配工作,而且可能是PGI编译器只是简单地对迭代进行了一些分区。您可以使用num_gangs和num_workers手动定义帮派/工作者的值,传递给这些子句的整数表达式可以取决于函数的值(参见OpenACC规范的2.5.7和2.5.8 )。
https://stackoverflow.com/questions/50934479
复制相似问题