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 调用的行为没有什么不同。 &amp;d_a[index]d_a + index 的解释完全由 C++ 规则处理。指针是指针。编译器不知道主机/设备。 如果你建议除此之外,如果你有另一个(我假设主机?)数组int[5],它位于 404 到 420,那么我会说不,那永远不会发生。 CUDA UVA system 保证了这一点。在 CUDA 之前,UVA 将是一个单独的案例。 CUDA UVA 保证主机和设备的地址空间(对于系统中的所有设备)是“协调的”,这意味着没有重叠,并且指针可以(理论上,无论如何)唯一确定它的值,关于它属于哪个实体。 在 UVA 之前有一个 CUDA 操作模型,其中这些陈述不成立,仍然可以使事情正常进行。此外,让我们明确一点,这与&amp;d_a[index]d_a + index 的等价性无关。这种等价性在编译时就可以发现,并且完全依赖于 C++,而不是任何特定于 CUDA 的东西。在编译时对指针的主机或设备关联一无所知。指针就是指针。

以上是关于CUDA 通过数组偏移量从设备内存中复制单个元素是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

CUDA中的一个简单的缩减程序

Cuda - 从设备全局内存复制到纹理内存

分配给设备内存的 CUDA 全局(如 C 语言)动态数组

Cuda:XOR 单个位集与位集数组

如何使用 CUDA C 快速压缩稀疏数组?

如何将嵌套结构的成员复制到 CUDA 设备的内存空间?