【问题标题】:OpenACC data movementOpenACC 数据移动
【发布时间】:2016-10-02 11:49:05
【问题描述】:

我是 OpenACC 的新手,我不太了解数据移动和“#pragma acc data”子句。

我有一个用 C 编写的程序。代码的摘录是这样的:

#pragma acc data create(intersectionSet[0:intersectionsCount][0:4]) // line 122
#pragma acc kernels // line 123
for (int i = 0; i<intersectionsCount; i++){ // line 124
    intersectionSet[i][0] = 9; // line 125
}

intersectionsCount 的值为 210395。通过以下方式编译并运行上述代码后:

pgcc -o rect_openacc -fast -Minfo -acc -ta=nvidia,time rect.c

我有这个输出:

    time(us): 1,475,607
122: data region reached 1 time
    31: kernel launched 210395 times
        grid: [1]  block: [128]
         device time(us): total=1,475,315 max=15 min=7 avg=7
        elapsed time(us): total=5,451,647 max=24,028 min=24 avg=25
123: compute region reached 1 time
    124: kernel launched 1 time
        grid: [1644]  block: [128]
         device time(us): total=292 max=292 min=292 avg=292
        elapsed time(us): total=312 max=312 min=312 avg=312
156: data region reached 1 time

阅读输出后我有一些问题:

  1. 我不知道为什么它说第 31 行,因为第 31 行没有 acc pragma。这是否意味着我无法追踪的东西?
  2. 在“31:内核启动210395次”行中,它表示它启动了210395次内核。我不知道内核需要启动这么多次是否正常,因为这部分花了5,451,647(us),我认为它有点长。我认为for循环很简单,不应该花太多时间。我是否以错误的方式使用了编译指示?

更新
我确实有几个程序的头文件。但这些文件没有“acc data”或“acc kernels”编译指示。

用“-Minfo=all”编译代码后,结果如下:

breakStringToCharArray:
 11, include "stringHelper.h"
      50, Loop not vectorized/parallelized: contains call
countChar:
 11, include "stringHelper.h"
      74, Loop not vectorized/parallelized: not countable
extractCharToIntRequiredInt:
 11, include "stringHelper.h"
      93, Loop not vectorized/parallelized: contains call
extractArray:
 12, include "fileHelper.h"
      49, Loop not vectorized/parallelized: contains call
isRectOverlap:
 13, include "shapeHelper.h"
      23, Generating acc routine vector
          Generating Tesla code
getRectIntersection:
 13, include "shapeHelper.h"
      45, Generating acc routine vector
          Generating Tesla code
getRectIntersectionInGPU:
 13, include "shapeHelper.h"
      69, Generating acc routine vector
          Generating Tesla code
max:
 13, include "shapeHelper.h"
      98, Generating acc routine vector
          Generating Tesla code
min:
 13, include "shapeHelper.h"
     118, Generating acc routine vector
          Generating Tesla code
main:
64, Loop not vectorized/parallelized: contains call
108, Loop not vectorized/parallelized: contains call
122, Generating create(intersectionSet[:intersectionsCount][:4])
124, Loop is parallelizable
     Accelerator kernel generated
     Generating Tesla code
124, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */

我是这样创建intersectionSet的:

intersectionSet = (int **)malloc(sizeof(int **) * intersectionsCount);
for (i = 0; i<intersectionsCount; i++){
    intersectionSet[i] = (int *)malloc(sizeof(int *) * 4);
}

【问题讨论】:

  • 1.嗯,这有点奇怪。你有从头文件中提取的任何代码吗? 2. 看起来编译器生成了一个包含 1 组 128 个线程的内核,因此它可能会多次启动该内核。你能用 -Minfo=all 发布编译输出吗?我敢打赌,它并没有像您认为的那样并行化。
  • @jefflarkin 我更新了帖子以显示使用“-Minfo=all”时的输出。

标签: pragma openacc


【解决方案1】:

发生的事情是,由于您有指向指针数组“**”的指针(至少我猜这就是 intersectionSet 的含义),编译器必须首先将指针分配给设备上的指针,然后循环遍历每个元素分配各个设备阵列。最后,它需要启动内核来设置设备上的指针值。这里有一些伪代码来帮助说明。

devPtrPtr = deviceMalloc(numElements*pointer size);
for (i=0; i < numElements; ++i) {
   devPtr = deviceMalloc(elementSize * dataTypeSize);
   call deviceKernelToSetPointer<<<1,128>>(devPtrPtr[i],devPtr);
}

为了帮助您的代码,我会切换维度,使列长为 4,行长为“intersectionsCount”。这也将有助于设备上的数据访问,因为“向量”循环应对应于 stride-1(连续)维度以避免内存分歧。

希望这会有所帮助,

垫子

【讨论】:

  • 我按照你提到的方式创建了我的intersectionSet(column=4,row=intersectionsCount。请参阅我的初始化更新)。还有什么我可以尝试的吗?谢谢
  • 您的更新显示 columns=intersectionsCount 和 row=4。
  • 尝试反转这些。分配大小为4的intersectionSet,然后将每个元素的大小调整为intersectionsCount。然后,当然,您的其余代码也需要更新。基本上,您在创建 intersetionSet 时所做的事情与编译器在设备上创建它时需要做的事情相同,除了启动内核以在指针数组中设置设备指针值。虽然列长度设置为 4,但它只需要启动 4 个内核而不是 210,395 个。
  • 感谢 Mat,切换维度确实提高了速度!然后我进一步研究了代码,发现如果我这样声明数组: int intersectionSet[intersectionsCount][4];它还提高了速度。你知道原因吗?
  • 不,这很好,但是为了填充设备上的指针,有一些额外的开销。你只是碰巧遇到了一个极端情况。
猜你喜欢
  • 2017-04-13
  • 2023-03-06
  • 2016-05-01
  • 2015-01-08
  • 2021-01-01
  • 1970-01-01
  • 2020-08-08
  • 2017-07-01
  • 1970-01-01
相关资源
最近更新 更多