Memory management cuda设备变量在不同功能中的分配和使用

Memory management cuda设备变量在不同功能中的分配和使用,memory-management,cuda,gpu,Memory Management,Cuda,Gpu,我是CUDA的新手,我有一个关于对象内存管理的问题。我有一个目标函数将数据加载到设备,如果调用另一个目标函数,则执行计算 我已经阅读了英伟达程序设计指南的一些部分和一些问题,但是它们只做一个函数的数据复制和计算,所以不需要多个函数。p> 更多规格: 数据读取一次。我不知道编译时的数据大小,因此需要动态分配。我当前的设备具有2.1的计算能力,很快将更新为6.1 我想在第一个函数中复制数据,并在另一个函数中使用数据。例如: __constant__ int dev_size; __device__

我是CUDA的新手,我有一个关于对象内存管理的问题。我有一个目标函数将数据加载到设备,如果调用另一个目标函数,则执行计算

<>我已经阅读了英伟达程序设计指南的一些部分和一些问题,但是它们只做一个函数的数据复制和计算,所以不需要多个函数。p> 更多规格: 数据读取一次。我不知道编译时的数据大小,因此需要动态分配。我当前的设备具有2.1的计算能力,很快将更新为6.1

我想在第一个函数中复制数据,并在另一个函数中使用数据。例如:

__constant__ int dev_size;
__device__ float* dev_data; //<- not sure about this

/* kernel */
__global__ void computeSomething(float* dev_output)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx < dev_size)
    {
        dev_output[idx] = dev_data[idx]*100; // some computation;
    }
}

// function 1
void OBJECT::copyVolumeToGPU(int size, float* data)
{
    cudaMalloc(&dev_data, size * sizeof(float));
    cudaMemcpy(dev_data, data, size * sizeof(float), cudaMemcpyHostToDevice );
    cudaMemcpyToSymbol(dev_size, size, sizeof(int));
}

// function 2
void OBJECT::computeSmthOnDevice(int size)
{
    // allocate output array
    auto host_output =  new float[size];
    float* dev_output;
    cudaMalloc(&dev_output, size * sizeof(float));

    int block = 256;
    int grid = ceil(size/block);
    computeSomething<<<grid,block>>>(dev_output);

    cudaMemcpy(host_output, dev_data, size * sizeof(float), cudaMemcpyDeviceToHost);

    /* ... do something with output ... */

    delete[] host_output;
    cudaFree(dev_output);
}
gpuerchk是这样执行的:但在本例中省略了


我可以使用uuu设备uuu指针(如uu设备uuuuu浮点*dev_数据)复制数据吗

一般来说,你的想法是可行的,但是:

cudaMalloc(&dev_data, size * sizeof(float));
这是不合法的。在主机代码中获取设备项的地址是不合法的。因此,如果您知道编译时的大小,最简单的方法是将其转换为静态分配,例如

__device__ float dev_data[1000]; 
如果你真的想让它成为一个动态分配的设备指针,那么你需要使用一种如所述的方法,这包括在主机代码中的一个典型设备指针上使用cudaMalloc,该指针是一个临时的,然后通过CUDAMEMCPITOSYMBOL将该临时指针复制到设备指针上。然后,当您想通过cudaMemcpy将数据复制到该特定分配中/从该分配中复制数据时,您可以使用cudaMemcpy从主机代码的临时指针复制数据


请注意,为了将数据从一个函数传递到下一个函数,或者从一个内核传递到下一个内核,没有理由不使用来自cudaMemcpy的动态分配指针,并将该指针传递到需要的任何位置。您甚至可以通过全局变量将其传递给任何需要它的宿主函数,就像普通的全局指针一样。但是,对于内核,您仍然需要通过内核参数将这样一个全局指针传递给内核。

通常,您的想法是可行的,但是:

cudaMalloc(&dev_data, size * sizeof(float));
这是不合法的。在主机代码中获取设备项的地址是不合法的。因此,如果您知道编译时的大小,最简单的方法是将其转换为静态分配,例如

__device__ float dev_data[1000]; 
如果你真的想让它成为一个动态分配的设备指针,那么你需要使用一种如所述的方法,这包括在主机代码中的一个典型设备指针上使用cudaMalloc,该指针是一个临时的,然后通过CUDAMEMCPITOSYMBOL将该临时指针复制到设备指针上。然后,当您想通过cudaMemcpy将数据复制到该特定分配中/从该分配中复制数据时,您可以使用cudaMemcpy从主机代码的临时指针复制数据


请注意,为了将数据从一个函数传递到下一个函数,或者从一个内核传递到下一个内核,没有理由不使用来自cudaMemcpy的动态分配指针,并将该指针传递到需要的任何位置。您甚至可以通过全局变量将其传递给任何需要它的宿主函数,就像普通的全局指针一样。但是,对于内核,您仍然需要通过内核参数将这样一个全局指针传递给内核。

您能试着勾勒出代码中的含义吗?因为要理解你想问什么并不容易。欢迎来到SO。请阅读这篇文章以改进你的问题。你能试着在代码中勾勒出你的意思吗?因为要理解你想问什么并不容易。欢迎来到SO。请阅读此文以改进您的问题。我正在尝试实施您的建议。你能解释一下你的最后一句话吗。我不明白你所说的通过命令行参数传递是什么意思。对不起,这是一个糟糕的词语选择。我编辑。我只是想让您将指针作为参数显式地传递给内核。我正在尝试实现您的建议。你能解释一下你的最后一句话吗。我不明白你所说的通过命令行参数传递是什么意思。对不起,这是一个糟糕的词语选择。我编辑。只是希望将指针作为参数显式传递给内核。