2013-03-22 4 views
0
----------------a.c--------------------- 
variable *XX; 
func1(){ 
    for(...){ 
    for(i = 0; i < 4; i++) 
     cutStartThread(func2,args) 
    } 
} 
---------------b.cu------------------- 
func2(args){ 
    cudaSetDevice(i); 
    xx = cudaMalloc(); 
    mykernel<<<...>>>(xx); 
} 
-------------------------------------- 

최근에 내 프로그램에 여러 GPU 장치를 사용하고 싶습니다. 내 노드에는 4 개의 Tesla C2075 카드가 있습니다. 4 개의 스레드를 사용하여 4 개의 GPU를 관리합니다. 또한 각 스레드의 커널이 여러 번 실행됩니다. 위와 같이 단순한 의사 코드.여러 커널과 여러 GPU에서 전역 메모리를 공유하는 방법은 무엇입니까?

  1. 변수 XX 매우 긴 문자열, 단지 커널에서 읽기 : 저는 두 가지 질문이 있습니다. mykernel의 여러 번 실행 중에이를 보존하려고합니다. cudaMalloc에 전화를 걸고 mykernel을 처음 실행했을 때만 mykernel에 포인터를 전달 하시겠습니까? 또는 한정자 __device__을 사용해야합니까?

  2. XX은 4 개의 스레드에서 사용되므로 파일의 전역 변수로 선언합니다. cudaMallocXX이 정확합니까? 예 : variable *xx[4]과 같은 배열을 사용해야합니까?

+0

자신의 코드에서'cuStartThread()'를 사용하지 마십시오. – talonmies

답변

1
  1. 단일 장치에서 실행중인 커널에 의해 사용의 경우, 생성 한 번 cudaMalloc를 호출 할 수있는 변수 XX 문자열을 잡고, 다음 (즉, XX) cudaMalloc에 ​​의해 생성 된 포인터 중 커널이 필요로하는 통과 .

    #define xx_length 20 
    char *XX; 
    cudaMalloc((void **)&XX, xx_length * sizeof(char)); 
    ... 
    kernel1<<<...>>>(XX, ...); 
    ... 
    kernel2<<<...>>>(XX, ...); 
    etc. 
    
  2. 각 스레드가 다른 장치에 액세스하기 위해 사용되는 것으로 가정하면, 각각의 스레드에 대한 별도의 XX 변수를 만든다. 이것이 정확히 얼마나 XX인지에 달려 있습니다. 그러나 배열 : 전역 범위에서

    char *XX[num_devices]; 
    

는 확인을해야합니다.

여러 개의 GPU를 관리하기 위해 여러 스레드를 사용하는 방법의 예로 CUDA OpenMP sample이 유용 할 수 있습니다.