我有这个简单的内核用于测试。
__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上,您可以将其解释为设备出于性能原因缓存内存,从而防止内存失效发生(或其他)
编辑:哎呀,我刚刚意识到这本书有多老了,我应该学会更好地阅读