2

我目前正在研究openacc API,我想知道是否可以在设备上创建一个数组,而主机上没有任何相应的分配数组。

假设我想使用我的旧的cuda kernel,并且只通过openacc API. 我需要一些仅在设备上使用的 256 个元素的数组。如果我只在主机上声明我的指针而不分配,它们可能有顺序地址。

如果我present_or_create在这些指针上使用了一个子句,我的大小为 256 个元素,我会在设备上以不同的数组结尾吗?或者主机上的连续地址,加上我的数组的长度,会被认为是同一个数组的一部分?

这里是一个例子:指针 A 的地址是 0,指针 B 的地址是 4。

如果我pcreateA[0:256]and上执行两个操作B[0:256],因为主机上的数据范围是[0 , 1024]and [4 , 1028],我最终会在设备上使用两个不同的 256 个元素数组,还是最终只有一个具有 range 的数组[0 , 1028]

我是否必须首先在主机上分配我的两个数组以确保有两个不同的数组,或者这种方法应该可以正常工作吗?

4

1 回答 1

2

我真的只能谈论 PGI 实现,但我认为 Cray 的工作方式类似。create/copy/present data 子句键在主机数据的地址上,以确定数据是否已经存在于设备上。如果你有一个指针 A 和一个指针 B 恰好具有相同的值(都指向同一个空间),那么 pcreate(A[0:256],B[0:256]) 将为 A 创建数据,然后 B 的 present_or_ 测试将看到数据已经存在。如果主机上的 A[0] 到 A[255] 与 B[0] 到 B[255] 重叠,则运行时也会看到重叠。重要的不是起始地址,而是整个范围。该模型是在设备上创建数据,该数据是主机上相同数据的镜像,“当前表”查找的“键”是主机地址范围。

在您的特定情况下,如果您的指针 A 的值为 0,那么,那是一个 NULL 指针并且被区别对待。因此,如果您有值为 4 的指针 A 和值为 8 的 B 并执行 pcreate(A[0:256],B[0:256]),您将为 A 复制 [4:256],然后运行时会注意到您正在尝试移动重叠但不包含在现有空间中的 B 范围。这在规范中是不允许的,我们的编译器也不支持。支持这一点需要在设备上重新分配 A 的数据,这可能意味着设备地址会移动。由于可以捕获这些地址,并且旧的陈旧地址将不再有效,因此这是不安全的事情。

于 2013-03-22T17:53:23.357 回答