CUDA 블록 / 워프 / 스레드는 어떻게 CUDA 코어에 매핑됩니까?


142

CUDA를 몇 주 동안 사용해 왔지만 블록 / 워프 / 스레드 할당에 대한 의구심이 있습니다. 교훈적인 관점 (대학 프로젝트) 에서 아키텍처를 연구하고 있으므로 최고 성능에 도달하는 것은 내 관심사가 아닙니다.

우선, 나는 이러한 사실들을 바로 잡았는지 이해하고 싶습니다.

  1. 프로그래머는 커널을 작성하고 스레드 블록 그리드에서 실행을 구성합니다.

  2. 각 블록은 스트리밍 멀티 프로세서 (SM)에 할당됩니다. 일단 할당되면 다른 SM으로 마이그레이션 할 수 없습니다.

  3. 각 SM은 자체 블록을 워프 (현재 최대 32 개의 스레드)로 분할합니다. 워프의 모든 스레드는 SM의 리소스에서 동시에 실행됩니다.

  4. 스레드의 실제 실행은 SM에 포함 된 CUDA 코어에 의해 수행됩니다. 스레드와 코어 사이에는 특정 매핑이 없습니다.

  5. 워프에 20 개의 스레드가 포함되어 있지만 현재 사용 가능한 코어가 16 개인 경우 워프가 실행되지 않습니다.

  6. 반면에 블록에 48 개의 스레드가 포함 된 경우 2 개의 워프로 분할되며 사용 가능한 메모리가 충분하면 병렬로 실행됩니다.

  7. 스레드가 코어에서 시작되면 메모리 액세스 나 긴 부동 소수점 연산을 위해 중단됩니다. 다른 코어에서 실행이 재개 될 수 있습니다.

그들이 맞습니까?

이제 GeForce 560 Ti를 사용하므로 사양에 따라 각각 48 개의 CUDA 코어 (전체 384 코어)를 포함하는 8 개의 SM이 장착되어 있습니다.

저의 목표는 아키텍처의 모든 핵심이 동일한 명령을 실행하도록하는 것입니다. 내 코드가 각 SM에서 사용 가능한 것보다 많은 레지스터를 요구하지 않는다고 가정하면 다른 접근법을 상상했습니다.

  1. 각 48 개의 스레드로 8 개의 블록을 만들어 각 SM에 1 개의 블록이 실행되도록합니다. 이 경우 SM에서 48 개의 스레드가 병렬로 실행됩니까 (사용 가능한 48 개의 코어를 모두 사용)?

  2. 6 스레드 64 블록을 시작하면 차이가 있습니까? (SM간에 균등하게 매핑된다고 가정)

  3. 예정된 작업에서 GPU를 "서브 머지 (submerge)"하면 (예를 들어 각각 1024 스레드의 1024 블록 생성) 모든 코어가 특정 시점에 사용되며 동일한 계산을 수행한다고 가정하는 것이 합리적입니다 (스레드가 마구간)?

  4. 프로파일 러를 사용하여 이러한 상황을 확인할 수있는 방법이 있습니까?

  5. 이 물건에 대한 참조가 있습니까? CUDA 프로그래밍 안내서와 "대량 병렬 프로세서 프로그래밍"및 "CUDA 응용 프로그램 설계 및 개발"에서 하드웨어 아키텍처 전용 장을 읽었습니다. 그러나 나는 정확한 답을 얻을 수 없었다.


"CUDA core"가 무엇인지 의견으로 추가하고 싶습니다. "CUDA core"또는 "Execution unit"은 완전히 파이프 라인 된 정수 ALU 및 FPU로, 하나의 cuda 스레드에서 클록주기 당 하나의 산술 명령어 명령을 실행합니다.
bruziuz

답변:


123

가장 좋은 참고 문헌 중 두 가지는

  1. NVIDIA Fermi 컴퓨팅 아키텍처 백서
  2. 리뷰 GF104

나는 당신의 각 질문에 대답하려고 노력할 것입니다.

프로그래머는 작업을 스레드로, 스레드를 스레드 블록으로, 스레드 블록을 그리드로 나눕니다. 컴퓨팅 작업 배포자는 스레드 블록을 SM (Streaming Multiprocessor)에 할당합니다. 스레드 블록이 SM에 분배되면 스레드 블록의 자원이 할당되고 (워프 및 공유 메모리) 스레드는 워프라고하는 32 개의 스레드 그룹으로 나뉩니다. 워프가 할당되면이를 활성 워프라고합니다. 두 워프 스케줄러는 사이클 당 두 개의 활성 워프를 선택하고 워프를 실행 단위로 디스패치합니다. 실행 단위 및 명령어 디스패치에 대한 자세한 내용은 1 p.7-10 및 2를 참조하십시오 .

4 ' . laneid (워프의 스레드 인덱스)와 코어간에 매핑이 있습니다.

5 분 . 워프에 32 개 미만의 스레드가 포함 된 경우 대부분의 경우 32 개의 스레드가있는 것과 동일하게 실행됩니다. 워프는 몇 가지 이유로 32 개 미만의 활성 스레드를 가질 수 있습니다. 블록 당 스레드 수는 32로 나눌 수 없으며, 프로그램은 분기 블록을 실행하여 현재 경로를 수행하지 않은 스레드가 비활성으로 표시되거나 워프의 스레드가 종료 된 것으로 표시됩니다.

6 ' . 스레드 블록은 WarpsPerBlock = (ThreadsPerBlock + WarpSize-1) / WarpSize로 나뉩니다. 워프 스케줄러가 동일한 스레드 블록에서 두 개의 워프를 선택할 필요는 없습니다.

7 ' . 실행 장치는 메모리 작동이 중단되지 않습니다. 명령을 발송할 준비가되었을 때 자원을 사용할 수없는 경우 나중에 자원을 사용할 수있을 때 명령이 다시 발송됩니다. 워프는 장벽, 메모리 작업, 텍스처 작업, 데이터 종속성 등에서 정지 될 수 있습니다. ... 정지 된 워프는 워프 스케줄러에서 선택할 수 없습니다. Fermi에서는 워프 스케줄러가 명령을 발행 할 수 있도록주기 당 최소 2 개의 워프를 갖는 것이 유용합니다.

GTX480과 GTX560의 차이점 은 참조 2 를 참조하십시오 .

참고 자료 (몇 분)를 읽으면 목표가 이해되지 않는다고 생각합니다. 나는 당신의 요점에 응답하려고 노력할 것입니다.

1 ' . kernel <<< 8, 48 >>>을 실행하면 32와 16 스레드의 2 개의 워프를 가진 8 개의 블록을 얻게됩니다. 이 8 개의 블록이 다른 SM에 할당 될 것이라는 보장은 없습니다. SM에 2 개의 블록이 할당되면, 각각의 워프 스케줄러가 워프를 선택하고 워프를 실행할 수있다. 48 개 코어 중 32 개만 사용합니다.

2 ' . 48 개 스레드의 8 개 블록과 6 개 스레드의 64 개 블록 사이에는 큰 차이가 있습니다. 커널에 분기가없고 각 스레드가 10 개의 명령어를 실행한다고 가정 해 봅시다.

  • 48 개의 스레드가있는 8 개의 블록 = 16 개의 워프 * 10 개의 명령어 = 160 개의 명령어
  • 6 개의 스레드가있는 64 개의 블록 = 64 개의 워프 * 10 개의 명령어 = 640 개의 명령어

최적의 효율성을 얻으려면 작업 분할이 32 스레드의 배수로 이루어져야합니다. 하드웨어는 다른 날실의 스레드를 통합하지 않습니다.

3 ' . 커널이 레지스터 또는 공유 메모리를 초과하지 않으면 GTX560은 한 번에 8 SM * 8 블록 = 64 블록 또는 8 SM * 48 워프 = 512 워프를 가질 수 있습니다. 주어진 시간에 작업의 일부가 SM에서 활성화됩니다. 각 SM에는 여러 실행 단위 (CUDA 코어 이상)가 있습니다. 주어진 시간에 어떤 리소스를 사용하고 있는지는 워프 스케줄러와 응용 프로그램의 명령어 조합에 따라 다릅니다. TEX 작업을 수행하지 않으면 TEX 장치가 유휴 상태가됩니다. 특수 부동 소수점 연산을 수행하지 않으면 SUFU 장치가 유휴 상태입니다.

4 ' . Parallel Nsight 및 Visual Profiler 쇼

ㅏ. IPC 실행

비. 발행 된 IPC

씨. 활성 사이클 당 활성 워프

디. 활성 사이클 당 적격 경사 (Night 만)

이자형. 뒤틀린 정지 이유 (Night 만)

에프. 명령 당 활성 스레드

프로파일 러에는 실행 단위의 사용률이 표시되지 않습니다. GTX560의 경우 대략적인 추정치는 IssuedIPC / MaxIPC입니다. MaxIPC의 경우 GF100 (GTX480)은 2 GF10x (GTX560)는 4이지만 목표는 3이 더 나은 목표라고 가정합니다.


1
답변 주셔서 감사합니다. 참고 문헌을 읽었지만 귀하의 답변에서 이해하지 못하는 몇 가지 사항이 있습니다. 다음 질문에서는 48 개의 코어 (16 개의 코어 * 3 개의 "코어 그룹")가있는 Fermi 아키텍처를 사용한다고 가정합니다. 1. 코어와 laneid 간의 매핑을 언급했습니다. 어떤 종류의 매핑입니까? 2. 참고로 각 "코어 그룹"은 클럭 사이클 당 최대 1/2 워프 (16 스레드)로 실행됩니다. 따라서 이론적으로 같은 블록에 48 개의 스레드가 있으면 3 개의 하프 워프로 구성되어 48 개의 코어에서 병렬로 실행됩니다. 내가 맞아?
Daedalus

1
CUDA 코어는 단정도 FP 장치의 수입니다. CUDA 코어의 관점에서 실행을 생각하는 것은 올바르지 않습니다. 각 날실에는 32 개의 스레드가 있습니다. 이 스레드는 실행 단위 그룹 (예 : 16 cuda 코어)에 발행됩니다. 단일 클럭에서 48 개 코어 모두에 발행하려면 두 워프 스케줄러 중 하나가 슈퍼 스칼라 쌍의 요구 사항을 충족하는 워프를 선택해야하며 두 명령 모두 CUDA 코어에 의해 실행되는 유형이어야합니다. 또한 다른 워프 스케줄러는 CUDA 코어가 다음 명령을 실행할 워프를 선택해야합니다.
Greg Smith

1
워프가 동일한 블록에 있거나 블록의 워프가 동일한 프로그램 카운터를 가질 필요는 없습니다.
Greg Smith

2
예제에서 각 스케줄러는 날실을 선택하고 1 개의 명령을 발행합니다. 이 경우 두 그룹의 실행 단위 만 사용됩니다. 더 많은 실행 단위를 사용하려면 스케줄러 중 1 개를 이중 발행해야합니다. 참고 문헌에서 알 수 있듯이 여러 유형의 실행 단위 (동전 된 cuda 코어뿐만 아니라)가 있으며 스케줄러가 이중 발행을 위해 충족 해야하는 명령 쌍 규칙 (잘 문서화되지 않음)이 있습니다.
Greg Smith

1
@GregSmith 저는 Fermi 아키텍처에서 SM 당 8 개의 활성 블록이 어디에서 나오는지 찾기 위해 웹을 검색하고 있습니다. 페르미 백서에는 언급되지 않았습니다. 그것에 대해 더 참조가 있습니까?
Greg K.

8

"E. 워프에 20 개의 스레드가 포함되어 있지만 현재 사용 가능한 코어가 16 개만 있으면 워프가 실행되지 않습니다."

부정확하다. 일반적인 의미에서 (CPU에서도 사용되는) 코어를 혼동하고 있습니다. GPU의 "멀티 프로세서"수와 nVIDIA 마케팅의 코어 ( "우리 카드에는 수천 개의 CUDA 코어가 있습니다")가 있습니다.

워프 자체는 단일 코어 (= 멀티 프로세서)에서만 예약 할 수 있으며 동시에 최대 32 개의 스레드를 실행할 수 있습니다. 단일 코어 이상을 사용할 수 없습니다.

숫자 "48 워프"는 컴퓨팅 성능 2.x를 갖는 nVIDIA GPU에서 멀티 프로세서 당 최대 활성 워프 (어떤주기에서 다음 사이클에서 작업하도록 예약 될 수있는 워프)의 최대 수입니다. 이 숫자는 1536 = 48 x 32 스레드에 해당합니다.

이 웹 세미나를 기반으로 답변


@GregSmith :이 문제를 해결하기 위해 답변을 편집했습니다. 인내심을 가졌지 만 5 년이 지났습니다 ...
einpoklum

단일 코어 (= 멀티 프로세서) 나는 질문이 단일 프로세서 = 멀티 프로세서가 아닌 프로세서를 가정한다고 생각합니다. 당신의 용어로 당신의 대답은 정확합니다.
Adarsh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.