openacc 循环中有多少个数组的私有副本

How many private copies of array are in the openacc loop

如果我有

#pragma acc parallel loop gang num_gangs(4) \
 num_workers(5) vector_length(6) private(arrayB)
 {
  for(j=0; j<len; j++)
  {
   ...
  }
 }

区域,我假设 4 个帮派中的每一个都有一个单独的 arrayB 副本(对于这个例子,你可以假设 arrayB 是一个包含 5 个元素的整数数组)。

  1. 我假设在上述情况下 4 个团伙中的每个团伙都有一份 arrayB 的私有副本(并且工人和向量,即一个团伙中的 5 个工人将看到arrayB 的单个私有副本在这 5 个工作人员之间共享,以及类似的向量)?还有,
#pragma acc parallel loop num_gangs(4) \
 num_workers(5) vector_length(6)
 {
  for(j=0; j<len; j++)
  {
   ...
  }
 }  

arrayB 的私有副本而言是否与上面的相同?

  1. 现在假设,
#pragma acc parallel loop gang worker \
 num_gangs(4) num_workers(5) \
 vector_length(6) private(arrayB)
 {
  for(j=0; j<len; j++)
  {
   ...
  }
 }

那么,谁拥有 arrayB 的私有副本,谁共享 arrayB 的单个私有副本?总共有多少 arrayB 的私人副本?

  1. 现在假设,
#pragma acc parallel loop gang vector \
 num_gangs(4) num_workers(5) \
 vector_length(6) private(arrayB)
 {
  for(j=0; j<len; j++)
  {
   ...
  }
 }

那么,谁拥有 arrayB 的私有副本,谁共享 arrayB 的单个私有副本?总共有多少 arrayB 的私人副本?

此外,如果我遗漏了任何其他可能的组合,请告诉我。

"private" 子句适用于应用循环中使用的最低调度(gang、worker、vector)。

因此 "loop gang private(arr.." 将为每个帮派拥有一个私有数组,该数组在该帮派内的工作人员和向量之间共享。

A "loop gang worker private(arr.." 将为每个工人拥有一个私有数组,该数组在该工人内的向量之间共享。

A "loop gang worker vector private(arr.." 将为每个未共享的向量创建一个私有数组。

对于案例 #1,创建的私有数组的数量将取决于编译器应用的循环计划。如果您使用的是 PGI 编译器,请查看编译器反馈消息 (-Minfo=accel) 以查看循环是如何安排的。如果这是一个打字错误并且您打算在此处包含一个 "gang",那么私有数组的数量将等于帮派的数量。

对于 #2,您有一个 "gang worker" 时间表,因此私有阵列的数量将是帮派数量和工人数量的乘积。

对于 #3,您有一个 "gang worker vector" 计划,因此私有数组的数量将是帮派数量、工人数量和向量长度的乘积。

请注意,一般来说,我不建议使用 "num_workers" 或 "vector_length",除非在知道内部循环的大小小于默认大小时进行更高级的性能调整,或调整寄存器使用时。否则,您将限制代码的并行性。

我也很少使用 "num_gangs"。仅当您拥有大量(或大小)私有数组并且限制帮派数量允许私有数组适合 GPU 的内存时才有意义。此外,在极少数情况下,需要为算法固定帮派数量(例如 RNG)。