2012-11-07 3 views
1

장치으로 정의 된 전역 메모리를 사용하는 CUDA에서 응용 프로그램을 수행하려고합니다. 이 변수는 .cuh 파일에 선언되어 있습니다.CUDA에서 전역 메모리를 올바르게 사용하려면 어떻게해야합니까?

다른 파일에서 .cu는 내가 cudaMallocs와 cudaMemCpy를 수행하는 주요 작업입니다. 내 코드의 일부이다

:

cudaMalloc((void**)&varOne,*tam_varOne * sizeof(cuComplex)); 
cudaMemcpy(varOne,C_varOne,*tam_varOne * sizeof(cuComplex),cudaMemcpyHostToDevice); 
varOne이 같은 .cuh 파일에 선언

:

__device__ cuComplex *varOne; 

내 커널 (나는 매개 변수로 varOne을 통과 아니에요 시작

) 디버거로 varOne을 읽으려고하면 변수를 읽을 수 없다고합니다. 포인터가 000..0을 처리하므로 분명히 잘못되었습니다.

그렇다면 어떻게 CUDA에서 전역 메모리를 선언하고 복사해야합니까?

+2

당신은 당신의 CUDA 호출에 확인 오류거야? –

답변

2

먼저 cuda에 복사 할 데이터를 저장할 포인터를 정의해야합니다. 위의 예제에서 우리는 array original_cpu_array를 cuda 전역 메모리로 복사합니다.

int original_cpu_array[array_size]; 
int *array_cuda; 

차지할 크기를 정의하십시오.

int size = array_size * sizeof(int); 

CUDA는 메모리 할당 :

msg_erro[0] = cudaMemcpy(original_cpu_array,array_cuda,size,cudaMemcpyDeviceToHost); 
:

msg_erro[0] = cudaMemcpy(array_cuda, original_cpu_array,size,cudaMemcpyHostToDevice); 

는 CPU에 GPU에서 커넬

복사를 실행합니다 GPU를 CPU에서

msg_erro[0] = cudaMalloc((void **)&array_cuda,size); 

복사 0

가능한 메모리 : 디버그

cudaFree(array_cuda); 

내가 정상적으로 배열 기능의 상태를 저장 (cudaError_t msg_erro [VAR]을). 그러나 이것은 반드시 필요한 것은 아니지만 할당이나 메모리 전송 중에 오류가 발생하면 시간을 절약 할 수 있습니다.

그리고

오류는 내가 좋아하는 뭔가를 사용하는 것보다 인쇄가 발생 한 경우 :

void printErros(cudaError_t *erros,int size, int flag) 
{ 
for(int i = 0; i < size; i++) 
    if(erros[i] != 0) 
    { 
     if(flag == 0) printf("Alocacao de memoria"); 
     if(flag == 1) printf("CPU -> GPU "); 
     if(flag == 2) printf("GPU -> CPU "); 
     printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i])); 
    } 
} 

플래그가 나에게 발생의 나 코드의 일부를 나타 내기 위해 기본적으로. 예를 들어 메모리 할당 후 :

msg_erro[0] = cudaMalloc((void **)&array_cuda,size); 
printErros(msg_erro,msg_erro_size, 0); 
0

일부 예제를 실험 해본 결과, 전달하지 않고 커널에서 전역 변수를 직접 사용할 수 없다는 것을 알았습니다. .cuh 파일로 초기화하더라도 main()에서 초기화해야합니다.

이유 : 당신이 세계적으로 선언하면

  1. , 메모리는 GPU 글로벌 메모리에 할당되지 않습니다. 메모리 할당에 cudaMalloc((void**)&varOne,sizeof(cuComplex))을 사용해야합니다. GPU에서만 메모리를 할당 할 수 있습니다. __device__ cuComplex *varOne; 선언은 프로토 타입 및 변수 선언처럼 작동합니다. 그러나 cudaMalloc((void**)&varOne,sizeof(cuComplex))을 사용할 때까지 메모리가 할당되지 않습니다.
  2. 또한 호스트 포인터로 처음에 main()에서 *varOne을 초기화해야합니다. cudaMalloc()을 사용하면 포인터가 장치 포인터임을 알게됩니다.

이 단계의 순서는 다음과 같습니다 (내 테스트 코드)

int *Ad;  //If you can allocate this in .cuh file, you dont need the shown code in main() 

__global__ void Kernel(int *Ad){ 
.... 
} 

int main(){ 
.... 
     int size=100*sizeof(int); 
     cudaMalloc((void**)&Ad,size); 
     cudaMemcpy(Ad,A,size,cudaMemcpyHostToDevice); 
.... 
} 
+1

이 대답의 추론과 방법론은 잘못되었습니다. 많은 쟁점이 있지만, 단지 하나만 골라 내면,이 선언은 :'__device__ int * Ad;'는 디바이스상의 포인터에 대한 기억 장치를 확실히 할당합니다. 단지 같은 코드가'__device__ '데코레이터. 게다가 우리는'uddevice__' 변수와 함께'cudaMalloc'이나'cudaMemcpy'를 사용하지 않습니다. 마지막으로, 코드에서'Ad'에 대한 여러 정의를 가지고 있습니다.이 정의는 가장 혼란스럽고 혼란스럽고 생각하는 것을 모호하게 만듭니다. –

+0

광고의 재 선언 변경. Ad에 __device__ 한정자를 사용하는 방법에 대한 설명서를 참조했습니다. 마지막 코드 예제는 http://docs.nvidia.com/cuda/cuda-c-programming-guide/#device-memory (공유하기 직전)에 나와 있습니다. – Fr34K

+0

그 코드 샘플은'__device__ float * devPointer;'변수를 선언하지만 그 변수와 함께'cudaMalloc' 또는'cudaMemcpy'를 사용하지 않습니다. 표시 한 코드가 올바르지 않습니다. –

관련 문제