2014-07-07 3 views
0

상수 메모리와 관련된 많은 SO 질문을 읽었으므로 왜 프로그램이 작동하지 않는지 아직 이해할 수 없습니다.CUDA 상수 메모리 값이 잘못되었습니다.

Common.cuh

__constant__ int numElements; 

__global__ 
void kernelFunction(); 

Common.cu

#include "Common.cuh" 
#include <stdio.h> 

__global__ 
kernelFunction() 
{ 
    printf("NumElements = %d", numElements); 
} 

Test.cu

#include "Common.cuh" 

int main() 
{ 
    int N = 100; 
    cudaMemcpyToSymbol(numElements,&N,sizeof(int)); 
    kernelFunction<<<1,1>>>(); 
    cudaDeviceSynchronize(); 
    return 0; 
} 

I을 다음과 같이 전체적으로 본다 t는 오류없이 컴파일하지만 numElements 값을 인쇄 할 때 나는 임의의 값을 얻는다. 누군가가 이것을 이해할 수있는 올바른 방향으로 나를 가리킬 수 있습니까?

답변

5

이 라인 :

__constant__ int numElements; 

는 컴파일 부 범위를 갖는다. 즉, 하나의 모듈과 다른 모듈로 컴파일하면 numElements__constant__ 메모리에 서로 다른 인스턴스가 생성됩니다.

해결 방법은 두 개의 모듈을 함께 장치 링크하기 위해 separate compilation and linking을 사용하는 것입니다. 이때 장치 링커가 두 모듈간에 기호를 확인합니다.

nvcc -arch=sm_20 -rdc=true -o test common.cu test.cu 

예 : 전용 ** Common.cu ** 상수 변수`numElements`을 사용하는 경우

$ cat common.cuh 
#ifndef COMMON_CU 
extern __constant__ int numElements; 
#endif 
__global__ 
void kernelFunction(); 
$ cat common.cu 
#define COMMON_CU 
#include "common.cuh" 
#include <stdio.h> 

__constant__ int numElements; 
__global__ 
void kernelFunction() 
{ 
    printf("NumElements = %d\n", numElements); 
} 
$ cat test.cu 
#define TEST_CU 
#include "common.cuh" 

int main() 
{ 
    int N = 100; 
    cudaMemcpyToSymbol(numElements,&N,sizeof(int)); 
    kernelFunction<<<1,1>>>(); 
    cudaDeviceSynchronize(); 
    return 0; 
} 

$ nvcc -arch=sm_20 -rdc=true -o test common.cu test.cu 
$ ./test 
NumElements = 100 
$ 
+0

이 잘 작동합니다. 그러나 ** Test.cu **에서 상수 변수를 사용하려면'nvlin 오류가 발생합니다 : numElements' 다중 정의 – BRabbit27

+1

아마도 당신은 대답을 읽고 코드를 자세히 읽어야합니다. test.cu *는 상수 변수에 쓰는 것과 동일한 상수 변수를 사용하고, 상수 변수에 쓰는 것은'kernelFunction'을 호출합니다. 다중 정의 오류는'numElements'가 한 곳에서만 정의 될 수 있기 때문에 발생합니다. 다른 곳에서는 'extern'으로 참조해야합니다. 답변을 다시 읽으십시오. –

+0

내 대답은 * more *가 컴파일 명령보다 코드와 다릅니다. 또한 헤더 파일의'numElements' * out * 정의를 소스 파일 중 하나 ('common.cu')로 옮겼습니다. 내 헤더 파일 ('common.cuh')에서는'extern'에 의해 numElements 만 참조하고, 그 헤더 파일이'common.cu '이외의 파일에 포함되어 있다면 * only *를 참조합니다. 따라서 명령 차이 만 컴파일하는 것이 아니라 내 대답과 코드 사이에 코드가 변경되었습니다. –

관련 문제