2013-05-16 121 views
2

我有一个内存分配问题,我不明白。我试图在GPU中分配一个char数组(我猜测它可能是内存碎片问题)。cuda内存碎片

这里是我的代码,

#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:内存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) 

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

+0

哪条线是31? – KiaMorot

+1

你的错误之一是'cudaMemcpy()'中的'&i'。它应该是'我'。 – BenC

+1

另外,您没有检查内核调用可能导致的错误。错误出现在那里,你以后只能捕捉它。 – BenC

回答

1

你的代码中有几件事情是错误的。

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

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

这里,如果你解决这些问题,你会得到什么:

#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; 
} 
+0

* cudaDeviceSynchronize()*不是必需的,因为* cudaMemcpy()*正在同步,因为您使用的是默认流0 – KiaMorot

+0

确实,我会在代码中添加更多评论。但他似乎是一位新的CUDA用户,正如@talonmies在他的文章中所说:“这可能会让初学者感到困惑,我建议在调试过程中在内核启动后使用显式同步,以便更容易地理解问题可能出在哪里正在出现“。 – BenC

+0

当我运行该程序时,出现“内存不足”错误。您可以帮助我解决此问题吗? – ParleBoy