今天我想测试如何在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之间的映射是实现随机和独立的吗?答案 0 :(得分:0)
问题末尾的“PS”在正确的轨道上。
OpenCL设备上的指针值是设备实现定义的,仅对特定设备上单个内核调用的生命周期有意义。对于从内核调用到内核调用的相同缓冲区使用不同基址的实现是合法的(尽管实现实际上可能不会实际执行此操作。)
因此,如果您确实将全局内存指针写入全局内存,那么您不应期望指针值在内核末尾之外有效。