【问题标题】:OpenCL autocorrelation kernelOpenCL 自相关内核
【发布时间】:2011-05-25 19:30:11
【问题描述】:

我编写了一个执行自相关的简单程序,如下所示...我使用 pgi 加速器指令将计算转移到 GPU。

//autocorrelation
void autocorr(float *restrict A, float *restrict C, int N)
{
      int i, j;
      float sum;
      #pragma acc region
      {
        for (i = 0; i < N; i++) {
                        sum = 0.0;
                for (j = 0; j < N; j++) {
                    if ((i+j) < N)
                      sum += A[j] * A[i+j];
                    else
                      continue;
               }
            C[i] = sum;
       }
       }
}

我在 OpenCL 中编写了一个类似的程序,但没有得到正确的结果。该程序如下...我是GPU编程的新手,所以除了可以修复我的错误的提示之外,欢迎任何其他建议。

__kernel void autocorrel1D(__global double *Vol_IN, __global double *Vol_AUTOCORR, int size)
{

    int j, gid = get_global_id(0);
    double sum = 0.0;

    for (j = 0; j < size; j++) {
            if ((gid+j) < size)
            {
               sum += Vol_IN[j] * Vol_IN[gid+j];
            }
            else
               continue;
               }

    barrier(CLK_GLOBAL_MEM_FENCE);
    Vol_AUTOCORR[gid] = sum;

}

由于我已将维度传递为 1,因此我正在考虑我的 get_global_size(0) 调用将为我提供当前块的 id,该块用于访问输入的一维数组。

谢谢,
萨彦

【问题讨论】:

  • 你得到了什么结果?如果您将Vol_AUTOCORR[gid] = sum; 更改为Vol_AUTOCORR[gid] = gid;,是否会为您提供预期的递增值数组?
  • 我在这里没有看到问题?你的主机代码是多少?您是否将数据正确传输到设备并返回?
  • 抱歉回复晚了...内核没有任何问题,我的主机代码有错误,导致结果出错。感谢您的评价。

标签: opencl


【解决方案1】:

代码是正确的。据我所知,这应该可以正常运行并给出正确的结果。

barrier(CLK_GLOBAL_MEM_FENCE); 不是必需的。没有这句话你会得到更快的速度。

您的问题应该在内核之外,检查您是否正确传递了输入,并且您正在从 GPU 中取出正确的数据。

顺便说一句,我假设您在进行双精度计算时正在使用双精度支持的 GPU。 检查您是否也传递了双值。请记住,您不能将浮点指针指向双精度值,反之亦然。这会给你错误的结果。

【讨论】:

  • 是的,我注意到在这种情况下不需要 BARRIER。感谢您向我指出数据类型。
猜你喜欢
  • 2011-12-06
  • 2016-01-17
  • 2018-02-08
  • 2013-04-24
  • 2013-05-01
  • 2019-05-26
  • 2012-02-05
  • 2017-11-05
相关资源
最近更新 更多