2016-09-25 2 views
-3

다른 CPU 스레드에서 다른 CUDA 스트림을 사용하는 프로그램을 구현했습니다. 메모리 복사는 해당 스트림을 사용하여 cudaMemcpyAsync을 통해 구현됩니다. 커널 시작은 또한 이러한 스트림을 사용합니다. 이 프로그램은 배정도 연산을 수행하고 있습니다. 그러나이 문제가 범인이라고 생각합니다. 그러나, cuBlas는 double의 행렬 곱셈에 대해 75-85 % CPU 사용량에 도달합니다. 또한 감소 작업이 있지만 if(threadIdx.x < s)을 통해 구현되며 s은 각 반복에서 2 회 감소하므로 다른 블록에서 사용 중지 된 워프를 사용할 수 있어야합니다. 응용 프로그램은 GPU와 CPU를 많이 사용하므로 이전 작업이 끝나 자마자 다른 작업으로 시작됩니다. 따라서 CPU 또는 GPU의 100 %에 도달 할 것으로 기대합니다.CUDA에서의 GPU 사용량이 낮음

문제는 내 프로그램이 GPU-1.9.0을 신뢰하는 경우 GPU로드의 30-40 % (CPU로드의 약 50 %)를 생성한다는 것입니다. 메모리 컨트롤러로드는 9-10 %, 버스 인터페이스로드는 6 %입니다. 이것은 CPU 코어 수와 동일한 수의 CPU 스레드 수입니다. CPU 스레드의 수를 두 배로하면로드는 CPU로드를 포함하여 거의 동일하게 유지됩니다.

왜 그렇습니까? 병목 현상은 어디에 있습니까?

나는 지포스 GTX 560을 사용하고 티, CUDA 8RC, MSVC++ 2013, 윈도우 (10)

한 내 생각 엔 윈도우 (10)는 GPU와 CPU 온도가 낮은 경우에도, 일부 적극적인 절전을 적용한다는 것입니다 전력 계획은 "고성능"으로 설정되고 전원 공급 장치는 700W이며 최대 CPU 및 GPU TDP로 전력 소비는 약 550W입니다.

또 다른 추측으로는 12 개의 단 정밀도 CUDA 코어 당 배정도 CUDA 코어가 카드에 1 개 있기 때문에 배정도 속도가 단 정밀도의 1/12이며 GPU-Z는 100 % 모든 단 정밀도 및 배정 밀도 코어가 사용되는 상황 그러나 숫자가 일치하지 않습니다.

+1

제공 한 정보를 기반으로 응용 프로그램의 성능을 제한하는 것에 대해 누군가가 말할 수 있다고 크게 기대하지 않습니까?NSight는이 목적을 위해 구체적으로 안내 된 성능 분석 및 메트릭을 제공합니다. 그것을 써. – talonmies

+0

@ talonmies, 나는 이것이 이중 정밀도에 대한 나의 추측이 맞다면 특히 일반적인 문제라고 생각했다. NSight는 최근 5xx 시리즈에 대한 지원을 중단 했으므로 사용할 수 없습니다. –

+0

페르미 카드는 여전히 Linux의 NSight에서 지원됩니다. 대신 시도해 볼 수 있습니다. 또는 최신 카드를 구입하십시오. 기대 이하의 성능은 문제가없는 공통된 문제이지만 그럴 이유가 하나도 없습니다. 그리고 누군가 코드 나 성능 메트릭없이 어떤 일이 벌어지고 있는지 말해 줄 수 있다고 상상합니까? – talonmies

답변

2

이유는 기본적으로 너무 많은 레지스터를 사용하는 CUDA 스레드로 인해 점유율이 낮았습니다. 스레드 당 레지스터 수에 대한 제한을 컴파일러에 알리려면 here과 같이 __launch_bounds__을 사용할 수 있습니다. 그래서 다음을 지정할 수 있습니다 블록 크기 256, 560 티의 모든 1536 개 스레드를 실행할 수 있도록 : CUDA 스레드 당 레지스터의 수를 제한 후

_global__ void __launch_bounds__(256, 6) MyKernel(...) { ... } 

의 GPU 사용량이 나를 위해 60 %로 상승했다 .

그런데 5xx 시리즈 카드는 Visual Studio 용 NSight v5.1에서 계속 지원됩니다. archive에서 It can be downloaded 다음 플래그가 더 여러 CPU 스레드에서 여러 GPU 스트림을 사용하는 응용 프로그램에서 70 %로 GPU 사용량 증가 :

편집

cudaSetDeviceFlags(cudaDeviceScheduleYield | cudaDeviceMapHost | cudaDeviceLmemResizeToMax); 
  • cudaDeviceScheduleYield는 CPU 스레드가있을 때 다른 스레드를 실행할 수 있습니다 결과에 대한 GPU 회전 대신 GPU 작동을 기다리고 있습니다.
  • cudaDeviceLmemResizeToMax은 내가 이해 한대로 커널 이 비동기로 실행되고 과도한 로컬 메모리가 발생하지 않도록합니다. 할당 & 할당 해제.