0

今天想测试一下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];
}

将buffer发回CPU并打印出来后,发现CPU内核返回的地址值是连续的,GPU返回的也是连续的,但是这两个地址空间是不连续的。我认为 CPU 和 GPU 在同一个缓冲区上工作,为什么缓冲区后半部分的地址与前半部分不连续?如果我只使用一个设备(CPU 或 GPU),那么所有地址都是正确连续的。有没有人可以帮我解决这个问题?因为我猜这可能是对GPU显存基本概念的误解,所以我想要一个详细的解释。

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

4

1 回答 1

0

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

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

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

于 2012-09-19T16:02:14.813 回答