2013-05-16 118 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