使用OpenACC并行化嵌套循环

时间:2018-04-03 20:27:45

标签: c parallel-processing openacc

我编写了一个涉及四个嵌套for循环的串行方法 - 我想使用OpenACC并行化这个方法(这是我第一次尝试使用它而且我对所有指令都不是很熟悉)。

我尝试了以下操作,但看到以下错误:call to cuStreamSynchronize returned error 700: Illegal address during kernel execution

我已经在下面粘贴了我的方法的简化伪代码版本,我非常感谢帮助找出并行化这四个嵌套循环结构的最佳方法。

// a, b, and c are input arguments to this method
#pragma acc parallel
for(int j = 0; j < a; j++){
    for(int i = 0; i < b; i++){

        // computing mins and maxs based on formulas with i, j, a, b, and c
        int minX = ...
        int maxX = ...
        int minY = ...
        int maxY = ...

        double count = (maxX - minX + 1)*(maxY - minY + 1);
        int sum1 = 0;
        int sum2 = 0;
        int sum3 = 0;

        #pragma acc loop
        for (int y = minY; y < maxY; y++) {
          for (int x = minX; x < maxX; x++) {
            #pragma acc routine(function_call_name) seq
            sum1 += // some function call;
            sum2 += // some function call;
            sum3 += // some function call;
          }
        }
        int result1 = (int)(sum1/count);
        int result2 = (int)(sum2/count);
        int result3 = (int)(sum3/count);

        #pragma acc routine(function_call_name) seq
        // calling some function call to store result1, result2, result3 in the output
    }
}

1 个答案:

答案 0 :(得分:1)

&#34;非法地址&#34;表示您的程序正在访问GPU上的错误地址。通常,这是由于越界访问,访问设备上的主机地址,使用带有动态数据成员的聚合数据结构而不是&#34;附加&#34;成员(即在父结构中设置设备指针)。不太常见的情况是堆或堆栈溢出。

您如何管理数据?代码中其他地方的数据区域?

如果使用PGI,请首先尝试定位多核CPU(-ta =多核),这样您就不必担心数据移动了。一旦平行区域工作,您就可以返回使用GPU并处理数据移动。我建议您首先使用CUDA统一内存(-ta = tesla:managed),以便CUDA驱动程序为您处理数据移动(仅限动态数据)。然后,一旦此功能正常,请尝试添加数据区域以手动管理数据。

我看到的其他事情:

parallel构造需要外部循环的循环指令。

#pragma acc parallel loop
for(int j = 0; j < a; j++){
    for(int i = 0; i < b; i++){

您可以考虑根据循环行程计数折叠循环:

#pragma acc parallel loop collapse(2)
for(int j = 0; j < a; j++){
    for(int i = 0; i < b; i++){

此外,&#34;例程&#34;指令应该修饰例程的原型或定义,但不应该在计算区域中使用。

如果您在设备例程中使用任何全局变量,请务必将其放入&#34;声明&#34;指令因此在设备上创建数据的全局副本。

如果您正在使用PGI,请添加&#34; -Minfo = accel&#34;编译器的选项。这将为编译器提供有关编译器如何并行化代码的反馈消息。

如果您没有使用数据指令,编译器将需要隐式复制数据。这些消息将告诉您正在复制的数组以及要复制的大小。

如果您无法理解反馈消息,请发布编辑中的输出,我将帮助您完成这些消息。