Memory 被全局内存和多个设备之间不一致的地址空间映射弄糊涂了

Memory 被全局内存和多个设备之间不一致的地址空间映射弄糊涂了,memory,opencl,Memory,Opencl,今天我想测试全局内存缓冲区是如何分配和存储在OpenCL中的,但结果让我感到困惑。我创建了一个全局内存缓冲区,并将其传递到一个内核中,这个内核构建在CPU和GPU设备上,但我将这个缓冲区的前半部分分配给CPU,剩余的一半分配给GPU,用不同的偏移量来指示CPU和GPU启动的不同起点,因此CPU和GPU可以同时在同一个缓冲区上工作,但是在不同的地方。然后在内核中,我使用&buffer[offset+tid]获取缓冲区中每个元素的地址,并将该地址再次存储到自身中 __kernel void foo(

今天我想测试全局内存缓冲区是如何分配和存储在OpenCL中的,但结果让我感到困惑。我创建了一个全局内存缓冲区,并将其传递到一个内核中,这个内核构建在CPU和GPU设备上,但我将这个缓冲区的前半部分分配给CPU,剩余的一半分配给GPU,用不同的偏移量来指示CPU和GPU启动的不同起点,因此CPU和GPU可以同时在同一个缓冲区上工作,但是在不同的地方。然后在内核中,我使用&buffer[offset+tid]获取缓冲区中每个元素的地址,并将该地址再次存储到自身中

__kernel void foo(__global uint * buffer, const uint offset)
{
    uint tid = get_global_id(0);
    buffer[offset+tid] = &buffer[offset+tid];
}
将缓冲区发送回CPU并打印出值后,我发现,CPU内核返回的地址值是连续的,GPU返回的也是连续的,但这两个地址空间彼此不连续。我认为CPU和GPU在同一个缓冲区上工作,为什么缓冲区的后半部分的地址与前半部分的地址不连续?如果我只使用一个设备(CPU或GPU),那么所有地址都是正确连续的。有人能帮我解决这个问题吗?因为我想这可能是对GPU内存基本概念的误解,所以我想要一个详细的解释

PS:我可以这样理解吗:虽然物理上只有一个缓冲区,但全局内存实际上是一个不透明的结构,不同设备返回的地址值会不同,因为全局内存和CPU之间的地址转换和映射,全局内存和CPU是随机和独立的实现?

问题末尾的“PS”是正确的

OpenCL设备上的指针值是设备实现定义的,并且仅对特定设备上的单个内核调用的生命周期有意义。实现在不同的内核调用之间为同一缓冲区使用不同的基址是合法的(尽管实现实际上可能不会这样做)


因此,如果您确实将全局内存指针写入全局内存,则不应期望该指针值在内核结束后仍然有效。

感谢您的回答,您的解释似乎是合理的。在AMD论坛上,主持人说这是因为OpenCL内存模型是宽松一致的,因此对于多个设备使用的缓冲区,运行时可能会将其复制到每个设备的内存中,以获得更好的访问速度,因此地址会有所不同。但我不认为它适用于APU内存,因为“融合”是它的特点,更不用说我在零拷贝区域分配了缓冲区。你的理解和我一样,这是非常有帮助的。Tks!