【问题标题】:Declaring device variables from main CUDA从主 CUDA 声明设备变量
【发布时间】:2017-06-26 05:06:30
【问题描述】:

我是 cuda 的新手,所以我希望我的问题不是完全离题。 我想在全局设备内存上创建一个数组,但我只会知道它在我的主要功能中间有多大(但在我访问设备之前)。

因为我不知道我不能在我的代码之前声明的大小: 设备 myArr[]

所以我想在 main 中创建一个指针 d_myArr,然后使用 cudaMalloc(d_myArr, arrSize) 在设备上分配内存,但我从未真正在设备上声明变量。

我看不到将 d_Arr 发送到我的内核的理由,因为它只会存在于该内核中(我认为?),我只是希望该变量首先作为全局变量存在于我的设备上,并且可以被不同的内核访问。

我可以在 main 中声明一个设备变量吗?如:

int main(){
   .
   .
   __device__ myArr[size];
   .
   .
}

如果是这样,它是否因某种原因而沮丧(因为我找不到这样做的人)。如果不允许这样做,我该怎么办?我看到有人提到 cudaMemcpyToSymbol,但我不知道它是否与我想要的完全相关,如果有人能准确解释如何使用它来实现我的需要,我会很高兴。

在一个附带问题上,我还有一个常量变量,我想在我的设备和主机上都存在。现在我只声明了两次,一次使用 device,一次没有,有没有更好的方法来做到这一点?

【问题讨论】:

    标签: c++ cuda


    【解决方案1】:

    这行不通。

    1. __device__ 变量必须在 global 范围内声明。
    2. __device__ 变量关联的分配大小必须在编译时知道。

    相反,只要您知道所需的分配大小,只需使用cudaMalloc 为变量分配空间。此方法允许动态分配全局变量。 __device__ 方法只允许静态分配全局变量。

    类似这样的:

    int main(){
       // ...
       int *d_data;
       cudaMalloc(&d_data, size*sizeof(int));
       // ... 
       kernel1<<<...>>>(d_data,...);
       // ... 
       kernel2<<<...>>>(d_data,...);
       // ...
    }
    

    如上所示,将这样一个动态分配的全局变量传递给多个内核是完全合法的,并且上面kernel1 放置在那里的数据或修改(如果有的话)将对运行的代码可见上面kernel2,就是我展示的例子。

    对于常量变量的问题,你提到的方法是合理的。如果您有这样在编译时未知的常量数据,这是一种明智的方法(您可能还希望使用__constant__ 而不是__device__ 进行调查)。另一方面,如果您有在编译时 已知的常量数据,则可以使用

     #define MYCONSTANT 123
    

     constant int myconstant=123;
    

    在全局范围内(即在main 之外)将允许在主机或设备代码中平等地使用这样的定义,而无需两次声明或管理它。最后一种方法适用于 POD 数据类型(例如 intfloatdouble 等),但不适用于 struct 等复杂类型。

    【讨论】:

    • 感谢您的回复!这样我就可以确保我正确理解了,因为我在设备中分配了内存,它不会丢失,即使我不使用 cudaMemcpy 来回获取信息,我的第二个内核中的 s_sata 将与最后留下的相同我的第一个内核,对吧?因此,只要我重新发送指向我所有内核的指针,它们都可以引用该变量,否则如果我不重新发送该变量,它仍然存在于分配的内存中,但我只是没有访问它的引用?跨度>
    • 是的,一旦您使用cudaMalloc 分配设备内存,它就会持久,直到您对其调用cudaFree 操作(或直到您的应用程序终止)。它的行为与任何其他内存一样。一旦你给它写了东西,后续的操作就可以看到写了什么,无论是后续的内核还是后续的cudaMemcpy操作。
    猜你喜欢
    • 2023-03-23
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2016-05-27
    相关资源
    最近更新 更多