2010-12-08 3 views
41

저는 CUDA 패러다임을 처음 접했습니다. 내 질문은 블록 당 스레드 수와 그리드 당 블록 수를 결정하는 데있다. 약간의 예술과 재판이 이것에 사용됩니까? 내가 찾은 것은 많은 것들이 이러한 것들을 위해 임의로 선택된 겉보기 숫자를 가지고 있다는 것입니다.블록 당 스레드를 결정하는 CUDA, 그리드 당 블록

나는 어떤 크기의 행렬을 곱셈을위한 방법에 전달할 수있는 문제를 고려하고 있습니다. 따라서 C의 각 요소 (C = A * B에서와 같이)는 단일 스레드에 의해 계산됩니다. 이 경우 스레드/블록, 블록/격자를 어떻게 결정합니까?

답변

66

일반적으로 블록/그리드의 크기를 데이터와 일치시키고 동시에 점유도, 즉 한 번에 활성화되는 스레드 수를 최대화하려고합니다. 점유에 영향을주는 주요 요소는 공유 메모리 사용, 레지스터 사용 및 스레드 블록 크기입니다.

CUDA 지원 GPU는 처리 능력이 SM (스트리밍 멀티 프로세서)으로 분리되어 있으며 SM의 수는 실제 카드에 따라 다르지만 여기서 간단하게 SM을 중점적으로 다룹니다 (모두 똑같이 작동합니다).). 각 SM은 32 비트 레지스터, 공유 메모리, 최대 활성 블록 수 및 최대 활성 스레드 수를 갖습니다. 이 수치는 GPU의 CC (연산 능력)에 따라 다르며 위키피디아 기사 http://en.wikipedia.org/wiki/CUDA의 중간에 있습니다.

커널은 커널이 32 비트 스레드에서 명령을 실행하기 때문에 스레드 블록 크기는 항상 32의 배수 여야합니다.예를 들어, 블록 크기가 50 개일 경우 GPU는 여전히 64 개의 스레드에 명령을 내리고 그 스레드를 낭비하게됩니다.

둘째, 공유 메모리와 레지스터에 대해 걱정하기 전에 카드의 계산 기능에 해당하는 최대 스레드 수와 블록 수를 기반으로 블록의 크기를 조정하십시오. 때로는 여러 가지 방법이 있습니다. 예를 들어 CC 3.0 카드의 경우 각 SM은 16 개의 활성 블록과 2048 개의 활성 스레드를 가질 수 있습니다. 즉, 블록 당 128 개의 스레드가있는 경우 2048 개의 스레드 제한을 초과하기 전에 SM에 16 개의 블록을 넣을 수 있습니다. 256 스레드를 사용하는 경우 8 개만 맞출 수 있지만 여전히 사용 가능한 모든 스레드를 사용하고 있으며 전체 사용량을 유지합니다. 그러나 블록 당 64 개의 스레드를 사용하면 16 개의 블록 한도에 도달 할 때 1024 개의 스레드 만 사용되므로 점유량은 50 %에 불과합니다. 공유 메모리 및 레지스터 사용이 병목 현상이 아닌 경우 데이터 차원 이외의 주요 관심사 여야합니다.

그리드의 주제에 ... 그리드의 블록이 SM을 통해 펼쳐지기 시작한 다음 나머지 블록이 파이프 라인에 배치됩니다. 해당 SM에 블록을 가져올만큼 충분한 리소스가있는 즉시 블록이 SM으로 이동되어 처리됩니다. 다시 말해, SM에서 블록이 완성되면 새로운 블록이 옮겨집니다. 이전 블록에서 256보다 작은 블록을 갖는 인수가 더 느린 블록으로 인해 리소스가 적어지기 때문에 더 빨리 완료 될 수 있습니다. 이것은 코드에 크게 의존합니다.

레지스터 및 공유 메모리에 대해서는 점유를 제한 할 수 있으므로 다음을 살펴보십시오. 공유 메모리는 전체 SM에 대해 유한하므로 가능한 한 많은 블록을 SM에 맞출 수 있도록 사용하십시오. 레지스터 사용에도 동일하게 적용됩니다. 다시 말하지만,이 수치는 컴퓨팅 성능에 따라 다르며 위키 피 디아 페이지에서 도표로 볼 수 있습니다. 행운을 빕니다!

+0

디바이스 기능을 사용하여 블록/스레드를 계산할 수없는 이유는 무엇입니까? 내가 2.1의 능력 (GT 520)을 가진 장치를 가지고 있기 때문에, 그것은 48 SM, 8 블록 각각과 블록 당 1024 스레드를 가지고있다. 나는 그것을 얻을 수 없다, 나의 질문이 바보 인 경우에 유감스러운. – greg

+0

일부 CUDA API를 사용하여 프로그래밍 방식으로 블록 당 최대 스레드 수를 결정할 수있는 방법이 있습니까? –

14

드문 경우이지만 블록 당 일정한 수의 스레드를 사용해야합니다. 그리드 당 블록 수는 행렬 곱셈의 경우 행렬 크기와 같은 문제 크기에 의해 결정됩니다.

블록 당 스레드 수를 선택하는 것은 매우 복잡합니다. 대부분의 CUDA 알고리즘은 광범위한 가능성을 인정하며 선택은 커널을 가장 효율적으로 실행하는 것을 기반으로합니다. 스레드 스케줄링 하드웨어가 작동하는 방식 때문에 거의 항상 32의 배수이고 최소 64입니다. 첫 번째 시도에 대한 좋은 선택은 CUDA 점유 계산기는 주어진 CUDA 커널하여 GPU의 멀티 점유을 계산 할 수 있습니다 128 또는 256

+0

블록 당 일정한 스레드에 대한 추론에 대해 더 잘 설명해 주시겠습니까? (또는 심지어 관련 기사를 링크). 감사합니다. –

16

http://developer.download.nvidia.com/compute/cuda/CUDA_Occupancy_calculator.xls

입니다. 멀티 프로세서 점유는 활성 워프와 GPU의 멀티 프로세서에서 지원되는 최대 워프 ​​수의 비율입니다. 장치의 각 다중 프로세서에는 CUDA 프로그램 스레드가 사용할 수있는 N 개의 레지스터 집합이 있습니다. 이 레지스터는 다중 프로세서에서 실행되는 스레드 블록간에 할당되는 공유 리소스입니다. CUDA 컴파일러는 머신에서 동시에 활성화 될 수있는 스레드 블록의 수를 최대화하기 위해 레지스터 사용을 최소화하려고 시도합니다. 프로그램이 스레드 당 사용 된 레지스터가 스레드 블록 크기가 N보다 큰 커널을 시작하려고하면 실행이 실패합니다 ...

2

또한 공유 메모리를 고려해야합니다 블록은 동일한 공유 메모리에 액세스 할 수 있습니다. 많은 공유 메모리를 필요로하는 것을 설계한다면 블록 당 더 많은 스레드가 유리할 수 있습니다.

예를 들어 문맥 전환과 관련하여 32의 배수가 모두 동일하게 작동합니다. 따라서 1D의 경우 64 개의 스레드가있는 1 개의 블록 또는 32 개의 스레드가있는 2 개의 블록을 실행하면 전역 메모리 액세스에 차이가 없습니다. 그러나 손에있는 문제가 자연스럽게 1 길이 64 벡터로 분해되면 첫 번째 옵션이 두 번째 옵션보다 더 좋습니다 (모든 스레드가 동일한 공유 메모리에 액세스 할 수있는 메모리 오버 헤드가 적음).

관련 문제