2011-05-06 5 views
2

은 내가 사용했습니다 : CUDA C에서CUDA는 장치 포인터 조작

float *devptr; 
//... 
cudaMalloc(&devptr, sizeofarray); 
cudaMemcpy(devptr, hostptr, sizeofarray, cudaMemcpyHostToDevice); 

가 할당하고 배열을 채 웁니다. 지금은 :하는 CUDA 커널을 실행하려면 해당 배열뿐만 오프셋 값

__global__ void kernelname(float *ptr) 
{ 
    //... 
} 

을 예컨대을 시도하고있다.

kernelname<<<dimGrid, dimBlock>>>(devptr+offset); 

그러나이 작동하지 않는 것 : C에서 는/C++는이 같은가 someting 될 것이다.

오프셋 값을 커널에 별도의 인수로 보내지 않고 커널 코드에서 오프셋을 사용하지 않고이를 수행 할 수있는 방법이 있습니까? 이 방법에 대한 아이디어가 있으십니까?

답변

6

포인터 계산이 CUDA에서 정상적으로 작동합니다. 호스트 코드의 CUDA 포인터에 오프셋을 추가하면 제대로 작동합니다 (오프셋은 바이트 오프셋이 아니라 일반 단어 또는 요소 오프셋 임).

EDIT : 간단한 동작 예 : 다음

#include <cstdio> 
int main(void) 
{ 

    const int na = 5, nb = 4; 
    float a[na] = { 1.2, 3.4, 5.6, 7.8, 9.0 }; 
    float *_a, b[nb]; 

    size_t sza = size_t(na) * sizeof(float); 
    size_t szb = size_t(nb) * sizeof(float); 

    cudaFree(0); 

    cudaMalloc((void **)&_a, sza); 
    cudaMemcpy(_a, a, sza, cudaMemcpyHostToDevice); 
    cudaMemcpy(b, _a+1, szb, cudaMemcpyDeviceToHost); 

    for(int i=0; i<nb; i++) 
     printf("%d %f\n", i, b[i]); 

    cudaThreadExit(); 
} 

하면, 두 번째 단어에서 복사되지 시작하는 제 cudaMemcpy 통화 장치 포인터에인가 된 워드 오프셋/요소를 볼 수 첫번째.

+0

답변 해 주셔서 감사합니다. 나는 그것이 바이트 오프셋이 아니라는 것을 알고있다. 그러나 나는 단어 크기가 무엇인지 모른다.포인터를 필요로하는 인덱스 번호를 단순히 추가하는 것입니다. C++ 에서처럼합니다. 그 맞습니까? – pmcr

+0

아마도이 편집을 통해 좀 더 명확하게 알 수 있을까요? – talonmies

+0

시간 내 주셔서 감사합니다. 그것은 매우 도움이되었습니다. 이제 작동 중입니다. 그것은 어리석은 실수였다. 나는 정말로 미안하다. – pmcr

1

포인터 연산은 호스트 측 코드에서 작동하며 nvidia에서 제공하는 예제 코드에서 자주 사용됩니다.

"선형 메모리는 장치에 40 비트 주소 공간으로 존재하므로 별도로 할당 된 엔티티는 포인터 (예 : 이진 트리)를 통해 서로 참조 할 수 있습니다."

더 읽기에서 :

그리고 성능 프리미티브 (NPP) 문서에서 http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#ixzz4KialMz00, 포인터 연산의 완벽한 예.

은 "4.5.1 선택 채널 소스 - 이미지 포인터 이이 채널의 이익 소스 이미지의 제 1 픽셀 내에서 포인터입니다. 예는 PSRC는 투자 수익 (ROI) 내부의 제 1 픽셀에 포인터 인 경우 적절한 셀렉트 채널 복사 프리미티브를 사용하면이 소스 이미지의 두 번째 채널을 포인터의 오프셋을 1만큼 오프셋하여 주어진이미지의 첫 번째 채널에 복사 할 수 있습니다. nppiCopy_8u_C3CR (pSrc + 1 , nSrcStep, pDst, nDstStep, oSizeROI); "

* 참고 : 컴파일러가 포인터의 데이터 형식을 인식하고 그에 따라 주소를 계산하기 때문에 데이터 요소 당 바이트 수를 곱하지 않고 작동합니다.

C 및 C++에서 포인터 연산은 위에서 설명한대로 또는 & ptr [offset] 표기법으로 수행 할 수 있습니다 (값 대신 데이터의 장치 메모리 주소를 반환하려면 값이 호스트 측 코드에서 장치 메모리에서 작동하지 않음). 표기법을 사용할 때 데이터 유형의 크기가 자동으로 처리되고 오프셋은 바이트가 아닌 데이터 요소 수로 지정됩니다.