CUDA 通过数组偏移量从设备内存中复制单个元素是不是安全?
Posted
技术标签:
【中文标题】CUDA 通过数组偏移量从设备内存中复制单个元素是不是安全?【英文标题】:CUDA is it safe to copy a single element from device memory by array offset?CUDA 通过数组偏移量从设备内存中复制单个元素是否安全? 【发布时间】:2021-03-07 10:30:10 【问题描述】:int main()
int n = 1000;
float *d_a;
cudaMalloc(&d_a, n * sizeof(float));
// do something that gives d_a value;
int index = rand() % n; // copy index
float res;
cudaMemcpy(&res, &d_a[index], sizeof(float), cudaMemcpyDeviceToHost);
cudaMemcpy(&res, d_a + index, sizeof(float), cudaMemcpyDeviceToHost);
// Are the above 2 the same and legal ?
cout << res << "\n";
return 0;
所以我有以下问题。我需要从设备数组中准确复制 1 个元素(随机索引)。我不想复制整个数组,因为这会很浪费。
那么,上述方法是否安全且符合 CUDA 编程指南?
【问题讨论】:
"以上2个一样吗?" -- 是的。 谢谢。它们在 CPU 上是相同的,但我不知道主机指向 GPU 内存的指针是否正确。关于主要问题,2 语句可以安全使用吗? 【参考方案1】:是的,您所展示的内容没有问题。这是合法的,应该将您想要的元素从设备复制到主机。
关于你的两种方法,它们是相同的(这是一个 C++ 问题,不特定于 CUDA)。
【讨论】:
我想知道,程序怎么知道 &d_a[index] 仍然是指向设备内存的指针? cudaMemcpy() 是否执行地址转换? 它没有。您正在做的是各种形式的指针算术。请记住,您在此问题中显示的所有代码都是 host 代码。通过适当的步骤,您可以直接使用主机编译器编译此代码,例如g++
。这里没有什么特别针对 CUDA 的。 cudaMemcpy
调用是一个 library 调用,与使用memcpy
library 调用的行为没有什么不同。 &d_a[index]
与 d_a + index
的解释完全由 C++ 规则处理。指针是指针。编译器不知道主机/设备。
如果你建议除此之外,如果你有另一个(我假设主机?)数组int[5]
,它位于 404 到 420,那么我会说不,那永远不会发生。 CUDA UVA system 保证了这一点。在 CUDA 之前,UVA 将是一个单独的案例。
CUDA UVA 保证主机和设备的地址空间(对于系统中的所有设备)是“协调的”,这意味着没有重叠,并且指针可以(理论上,无论如何)唯一确定它的值,关于它属于哪个实体。
在 UVA 之前有一个 CUDA 操作模型,其中这些陈述不成立,仍然可以使事情正常进行。此外,让我们明确一点,这与&d_a[index]
和d_a + index
的等价性无关。这种等价性在编译时就可以发现,并且完全依赖于 C++,而不是任何特定于 CUDA 的东西。在编译时对指针的主机或设备关联一无所知。指针就是指针。以上是关于CUDA 通过数组偏移量从设备内存中复制单个元素是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章