【问题标题】:Temporary CUDA Device Arrays临时 CUDA 设备阵列
【发布时间】:2013-12-06 18:24:09
【问题描述】:

几个月来一直在玩这个宏大的 CUDA 实验,我发现自己在做更多的实验,并试图从教程示例中抽离出来。

我的问题是:如果我只想将 GPU 上的数组用于临时存储之类的东西,而不将它们复制回主机进行显示/输出,我可以只使用__device__ double array[numpoints]; 创建一个设备数组吗?那么对于任何我想从 GPU 拿回来,我需要做整个 cudaMalloc、cudaMemcpy 的 spiel,对吗?此外,一种方法或另一种方法之间有什么区别吗?我以为他们都在全局内存中创建数组。

【问题讨论】:

    标签: c++ cuda


    【解决方案1】:

    请参阅this 关于__device__ 限定符的说明。因此,如果您声明它__device__,您将无法通过cudaMemcpy 在主机中访问它,但链接中还提到了其他内容。

    您可以做的是在主机代码中声明一个全局指针(即不带__device__)并使用cudaMalloc 进行分配。因此,您可以使用 cudaMemcpy 将结果复制回主机。

    【讨论】:

    • cudaMemcpy 可用于复制到静态声明的__device__ 内存。这就是cudaGetSymbolAddresscudaGetSymbolSize 的用途——您可以在运行时获取静态符号的详细信息,然后像使用任何其他主机地址一样使用它们。
    • @talonmies :很高兴知道这一点。刚试过,它的工作原理谢谢。如果您回答相同,我会投票赞成(看起来这就是问题的发布者正在寻找的内容)。
    【解决方案2】:

    您可以创建、填充和使用全局内存数组,而无需使用cudaMemcpy 从主机复制数据以进行初始化,如果这是您的要求。在下面的简单示例中,我创建了一个直接在设备上初始化的全局内存数组,然后在不再需要时释放它。

    #include<stdio.h>
    
    __global__ void init_temp_data(float* temp_data) {
        temp_data[threadIdx.x] = 3.f;
    }
    
    __global__ void copy_global_data(float* temp_data, float* d_data) {
        d_data[threadIdx.x] = temp_data[threadIdx.x];
    }
    
    #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
    inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
    {
        if (code != cudaSuccess) 
        {
            fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
            if (abort) exit(code);
        }
    }
    
    int main() {
    
        float* data = (float*)malloc(16*sizeof(float));
        float* d_data; gpuErrchk(cudaMalloc((void**)&d_data,16*sizeof(float)));
        float* temp_data; gpuErrchk(cudaMalloc((void**)&temp_data,16*sizeof(float)));
    
        init_temp_data<<<1,16>>>(temp_data);
        gpuErrchk(cudaPeekAtLastError());
        gpuErrchk(cudaDeviceSynchronize()); 
    
        copy_global_data<<<1,16>>>(temp_data,d_data);
        gpuErrchk(cudaPeekAtLastError());
        gpuErrchk(cudaDeviceSynchronize()); 
    
        gpuErrchk(cudaFree(temp_data));
        gpuErrchk(cudaMemcpy(data,d_data,16*sizeof(float),cudaMemcpyDeviceToHost));
    
        for (int i=0; i<16; i++) printf("Element number %i is equal to %f\n",i,data[i]);
    
        getchar();
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-04
      • 1970-01-01
      • 2014-10-18
      • 2013-03-25
      • 2012-04-24
      • 2013-04-10
      • 2012-11-29
      • 1970-01-01
      • 2021-02-06
      相关资源
      最近更新 更多