【问题标题】:OpenCL. Weird bug with array addressing/pointersOpenCL。数组寻址/指针的奇怪错误
【发布时间】:2012-07-15 23:12:53
【问题描述】:

我有这个简单的内核用于测试。

__kernel void nfa(__global const int *a, __global int *output)
{
        output[0] = a[0];
}

注意:这是在 cpu 上运行的,内存可能在主机上。它会导致此错误。

* 检测到 glibc ./program: malloc(): smallbin 双链表已损坏:0x0000000000a4a540 **

我怀疑这会以某种方式破坏程序的一部分,因为它正在访问主机内存。但据我所知,所有内存都正确分配。它在堆栈上,但在运行时保持在范围内。

但是,如果我这样做:

   __kernel void nfa(__global const int *a, __global int *output)
    {
            a = a;
            output[0] = a[0];
    }

结果是答案 2,这是正确的,因为 a 是具有 [2, 4, 8] 的数组;

对其自身的分配解决了问题...

这也可以,结果是4。

   __kernel void nfa(__global const int *a, __global int *output)
    {
            output[0] = a[1];
    }

似乎只是访问 a[0],而不分配给它自己会导致问题。

有人知道怎么回事吗?

我在 Linux 上使用 AMD OpenCL 驱动程序(使用英特尔 CPU,但我有 AMD 卡)。

编辑:

创建缓冲区的代码(精简下来,数组和缓冲区之间还有其他代码):

int a[3];
a[0] = 2;
a[1] = 4;
a[2] = 8;

cl::Buffer bufferA = cl::Buffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR , sizeof(int) * 3, &a);

【问题讨论】:

  • 你是用 malloc 还是用 clCreateBuffer() 分配内存的?我相信后者是必需的,即使您使用的是 CPU 设备。
  • 内存在堆栈上。使用了 clCreateBuffer(它的等价物我正在使用 c++ 绑定),并且 clCreateBuffer 方法将指针传递给数组,它使用标志“CL_MEM_USE_HOST_PT”。据我所知,这可能导致直接使用内存并将其复制到 GPU。由于我没有使用 GPU,所以它在主机上。
  • 我们能看到你的 clSetKernelArg() 调用吗?
  • 为什么不使用 CL_MEM_COPY_HOST_PTR 进行测试?我的意思是,我不明白你是如何确保 OpenCL 在函数返回后不访问数组的?

标签: c linux arrays pointers opencl


【解决方案1】:

我可能错了(我没有使用 C++ OpenCL,但我相信它与 C 绑定大致相同)但我相信:

调用 cl::Buffer 的最后一个参数类型是 void*。你想要的是一个指向你传入的内存块的指针,在这种情况下是数组(因为数组,它会自动转换为指针)。您已将 pointer 传递给数组(即指向指针的指针),编译器会悄悄地将其强制转换为 void*。这意味着,您最终会复制数组指针,然后在内存中复制 2 个整数之后发生的任何事情。我可以想象这会导致糟糕的结果

我不确定为什么 a=a 或 output = a[1] 会修复它,因为我没有做 CPU OpenCL 的经验,我不确定具体是如何工作的。在 GPU 上,您可能可以将其解释为设备出于性能原因缓存内存,从而防止发生内存失效(或其他情况)

编辑:哎呀,我才意识到这是几岁了,我应该学会更好地阅读

【讨论】:

    猜你喜欢
    • 2013-06-12
    • 2015-02-22
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多