2012-09-10 4 views
0

GTX690 (듀얼 칩) 보드에서 동일한 커널을 실행해야하는 코드를 작성하고 있습니다. 계산은 꽤 분리 가능하기 때문에 장치간에 데이터 교환이 필요하지 않으며 결과를 CPU에 병합합니다. 각 장치에서 코드를 실행하는 방법과 각 장치의 메모리 공간에 I/O 데이터 공간을 제공하는 방법을 이해합니다.CUDA 멀티 gpu : 동일한 커널 실행 (듀얼 칩 디바이스)

두 장치에서 실행되는 커널이 사용하는 상수를 설정하려고 할 때 문제가 발생합니다. 각 장치에 대해 배열을 만들어야합니까? 그렇다면 커널에서 어떤 장치가 실행 중인지 확인하여 배열에서 적절한 상수에 액세스 할 수 있습니까?

다음은 일부 코드입니다. 1 칩만 사용하는 경우 (numDev = 1 설정) 올바르게 작동하지만 둘 다 사용하지는 않습니다.

__constant__ float d_cellSizeZ; 
std::vector<int*> d_cell; 
................. 
bool Init(int cellsN_, float size_){ 
    bool res = true; 
    if(cudaSuccess != cudaGetDeviceCount(&numDev)) 
    return false; 
    //numDev = 1; 
    d_cl.resize(numDev); 
    for(int i = 0; i < numDev; ++i){ 
    res &= (cudaSuccess == cudaSetDevice(i)); 
    if(!res) 
     break; 
    res &= (cudaSuccess == cudaMalloc((void**)&d_cell[i], cellsN_*sizef(int))); 
    }; 
    res &= (cudaSuccess == cudaMemcpyToSymbol(d_cellSizeZ, &size_, sizeof(float))); 
    if(!res) 
    Cleanup(); 
    return res; 
} 

커널에서는 단지 d_cellSizeZ 상수를 사용합니다. 그렇다면 각 장치가 동일한 커널에서 잘 사용되도록 어떻게 일정하게해야합니까?

또 다른 질문은 : 장치간에 데이터를 교환하려고하면 PCI 버스를 통과합니까 아니면 듀얼 칩 보드에 내부 경로가 존재합니까?

+1

각 장치마다 다른 CUcontext가 있습니다. cudaSetDevice를 호출하면 호스트 스레드가 현재 활성 CUcontext로 전환됩니다. CUcontext마다 CU 모듈이로드됩니다. 현재 장치 [numDev - 1]에서만 기호를 설정하고 있습니다. cudaMemcpyToSymbol을 for 루프로 옮겨보십시오. 그러면 결과가 각 CUcontexts 메모리 공간에 복사됩니다. –

+0

네, 그게 제가 생각한 것입니다.하지만 상상하는 것이 포인터와 같이 부드러워서 두 번째 호출이 이전 장치에 설정된 값을 덮어 쓰거나 이름의 일부 일 뿐이므로 저를 괴롭 히고 있습니다. 각 장치는 상수 메모리에 자신의 포인터에 해당합니까? – neworld

+0

불행히도 멀티 GPU에 대한 정보가 너무 적습니다. 대부분 프로페셔널 멀티 테슬라 시스템과 관련이 있습니다. 만약 당신이 조언을 일부 문서/예제 듀얼 칩 deices와 함께 일하는 것에 대해 감사 할 것입니다 :) – neworld

답변

2

마지막 장치에서는 d_cellSizeZ 만 초기화하므로 다른 장치에서는 정의되지 않습니다. 당신은 각 장치에 d_cellSizeZ을 초기화 할 필요가, 가장 쉬운 방법은 그렉 의견 제안 루프 내부에서 그렇게하는 것입니다

for(int i = 0; i < numDev; ++i) 
{ 
    checkCudaErrors(cudaSetDevice(i)); 
    checkCudaErrors(cudaMalloc((void**)&d_cell[i], cellsN_*sizef(int))); 
    checkCudaErrors(cudaMemcpyToSymbol(d_cellSizeZ, &size_, sizeof(float))); 
}; 

그것은 d_cellSizeZ 기호의 재사용 주위에 약간 이상한 얻을 않습니다. 뒤에서 약간의 영리함이 있지만 기본적으로 cudaMemcpyToSymbol() 함수는 현재 활성화 된 장치에서 심볼을 조회하므로 매번 올바른 장치로 복사됩니다.