c-OpenCL.数组寻址/指针出现奇怪错误



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

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

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

*glibc检测到/程序:malloc():smallbin双链表已损坏:0x00000000004a540**

我怀疑这在某种程度上破坏了程序的一部分,因为它正在访问主机内存。但据我所知,所有内存都分配正确。它在堆栈上,但在运行时保持在作用域中。

然而,如果我这样做:

   __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];
    }

似乎只是访问[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);

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

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

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

编辑:哎呀,我刚刚意识到这本书有多老了,我应该学会更好地阅读

最新更新