memory-management - cuda中的内存碎片

标签 memory-management cuda gpu

我遇到了一个我无法理解的内存分配问题。我正在尝试在 GPU 中分配一个字符数组(我猜测这可能是内存碎片问题)。

这是我的代码,

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cuda.h>

inline void gpuAssert(cudaError_t code, char *file, int line, 
                 int abort=1)
{  
   if (code != cudaSuccess) {
      printf("GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }

__global__ void calc(char *k,char *i)
{
       *i=*k;
}
int main()
{
        char *dev_o=0;
        char *i;
        i = (char*)malloc(10*sizeof(char));

        cudaMalloc((void**)&dev_o,10*sizeof(char)); //Line 31


        calc<<<1,1>>>("arun",dev_o);

        gpuErrchk(cudaMemcpy(&i,dev_o,10*sizeof(char),cudaMemcpyDeviceToHost));

        cudaFree(dev_o);

        printf("string : %s \n",i);

        return 0;
}

但我得到的输出为,

GPUassert: out of memory sample2.cu 31

在同样的情况下,我尝试在 GPU 中分配整数并且它工作正常。

我的 GPU 设备信息如下:

--- General Information for device 0 ---
Name:GeForce GTX 460 SE
Compute capability:2.1
Clock rate:1296000
Device copy overlap:Enabled
Kernel execition timeout :Enabled
--- Memory Information for device 0 ---
Total global mem:1073283072
Total constant Mem:65536
Max mem pitch:2147483647
Texture Alignment:512
--- MP Information for device 0 ---
Multiprocessor count:6
Shared mem per mp:49152
Registers per mp:32768
Threads in warp:32
Max threads per block:1024
Max thread dimensions:(1024, 1024, 64)
Max grid dimensions:(65535, 65535, 65535)

谁能告诉我问题是什么以及如何克服它?

最佳答案

您的代码中有几处错误。

  1. cudaMemcpy(&i, ...)应该是cudaMemcpy(i, ...) .
  2. 检查内核调用的返回错误,如 this post 中所述。 。如果不这样做,错误似乎会稍后出现在您的代码中。

    gpuErrchk(cudaPeekAtLastError());
    gpuErrchk(cudaDeviceSynchronize());
    
  3. 内核的 char *k 参数是一个主机指针。在调用内核之前,您应该创建另一个设备数组并将数据复制到设备。
  4. 您也没有在 calc() 内核中的线程上执行任何并行工作,因为您没有使用线程索引 threadIdx.x。不过这可能是为了测试。

如果解决这些问题,您将得到以下结果:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cuda.h>

inline void gpuAssert(cudaError_t code, char *file, int line, 
                 int abort=1)
{  
   if (code != cudaSuccess) {
      printf("GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }

__global__ void calc(char* k, char *i)
{
       i[threadIdx.x] = k[threadIdx.x];
}

int main()
{
        const char* msg = "arun";

        char *dev_i, *dev_k;
        char *i, *k;

        k = (char*)malloc(10*sizeof(char));
        i = (char*)malloc(10*sizeof(char));

        sprintf(k, msg);

        cudaMalloc((void**)&dev_i, 10*sizeof(char));
        cudaMalloc((void**)&dev_k, 10*sizeof(char));

        gpuErrchk(cudaMemcpy(dev_k, k, 10*sizeof(char), cudaMemcpyHostToDevice));

        calc<<<1,5>>>(dev_k, dev_i);

        gpuErrchk(cudaPeekAtLastError());
        // Synchronization will be done in the next synchronous cudaMemCpy call, else
        // you would need cudaDeviceSynchronize() to detect execution errors.
        //gpuErrchk(cudaDeviceSynchronize());

        gpuErrchk(cudaMemcpy(i, dev_i, 10*sizeof(char), cudaMemcpyDeviceToHost));

        printf("string : %s\n", i);

        cudaFree(dev_i);
        cudaFree(dev_k);
        free(i);
        free(k);

        return 0;
}

关于memory-management - cuda中的内存碎片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16584322/

相关文章:

opencl - OpenCL SDK 无法找到 Ivy bridge 的 IGP

opencv - OpenCV中adaptiveThreshold()的GPU实现

ios - 2 MB的GIF图像占用8 MB的内存

c - 通过计算复制 C 数组的更快方法

c++ - 如何将 3D 数组转换为 1D 数组?

c - 测量 CUDA 内核时的时间不同

python-3.x - 如何使用 GPU 中的 panda dataframe 读取 csv 文件?

C和MPI : function works differently with same data

objective-c - 内存管理

CUDA : How to detect shared memory bank conflict on device with compute capabiliy >= 7. 2?