
들어가기 앞서서
NVIDIA는 Fermi를 시작으로 유사한 원리 아키텍처를 사용하여 모든 진행 중인 작업을 관리하는 스트리밍 멀티프로세서(SM)내에서 Wrap Scheduler를 도입했음.
GPU는 여러 개의 GPC(Graphics Processing Cluster)로 나뉘며(참고로 GPC는 케이플러때부터 도입된 개념),
각 GPC는 여러 개의 SM(SMX, SMM)과 하나의 래스터 엔진(Raster Engine)을 가지고 있다고 함.
이들 사이에는 많은 연결이 있으며, 가장 두드러진 것은 GPC와 다른 기능 모듈(예: ROP 또는 다른 서브시스템)을 연결하는 Crossbar 임.
(crossbar는 데이터 병목을 줄이고 통신 최적화하는 역할을 함)
프로그래머가 작성한 셰이더는 SM에서 처리됨. 각 SM은 많은 Core(코어)를 포함하며, 이 Core들은 스레드의 수학 연산을 수행.
예시를 들자면, 하나의 스레드는 정점 또는 픽셀 셰이더 호출이 될 수 있음
이러한 Core와 다른 Unit 들은 Warp Scheduler에 의해 관리되며, Warp Scheduler는 32개의 스레드를 그룹화한 Warp(스레드 묶음)를 관리하고 실행할 명령을 Dispatch Units로 전달함.
GPU에 실제로 얼마나 많은 이러한 유닛(각 GPC에 몇 개의 SM, 몇 개의 GPC 등)이 있는지는 칩 구성 자체에 따라 다름.
예를 들어, GM204는 4개의 GPC를 가지고 있으며, 각 GPC는 4개의 SM을 가지고 있음
반면 Tegra X1은 1개의 GPC와 2개의 SM을 가지고 있으며, 둘 다 Maxwell 설계를 채택함.
SM 설계 자체(코어 수, 명령 유닛, 스케줄러 등)도 시간이 지남에 따라 변화하며, 이는 칩을 고성능 데스크탑에서부터 노트북 모바일까지 확장할 수 있도록 도와줌
(여기서 맥스웰 아키텍쳐는 2014년에 소개된 이전의 켈러 아키텍쳐를 대처하는 설계임. Streaming Multiprocessor 개선해서 SMM으로 전력 효율성을 높이고 더 많은 스레드를 동시 처리해주는게 핵심임. 이후에 파스칼->볼타->튜링->엠페러로 이어짐)

(Streaming Multiprocessor)
페르미 SM 제품군을 예시로 이 파이프라인 로직에 대해서 설명하자면

1.프로그램은 그래픽 API(DX, GL, WEBGL)를 통해 드로우콜(drawcall)을 발행하며,
이 명령은 드라이버 프로그램으로 전달.
드라이버는 명령의 유효성을 검사한 후, 이 명령을 GPU가 읽을 수 있는 Pushbuffer에 넣음.
2.일정 시간이 지나거나 명시적으로 flush 명령이 호출되면, 드라이버 프로그램은 Pushbuffer의 내용을 GPU로 전송.
GPU는 호스트 인터페이스(Host Interface)를 통해 이러한 명령을 수신하고, 프론트 엔드(Front End)에서 이러한 명령을 처리
3. 원시 할당기(Primitive Distributor)에서 작업 할당이 시작되며, indexbuffer에 있는 정점을 처리하여 삼각형을 생성하고 배치(batches)로 나누어 여러 PGCs로 전송함. 이 단계의 이해는 n개의 삼각형이 만들어지면, 이들을 여러 PGC에 동시에 처리하도록 할당하는 것임.

4. GPC내의 각 SM 내의 Ploy Morph Engine은 삼각형 인덱스(triangle indices)를 통해 삼각형의 데이터(vertex data)를 가져오는 역할을 함. 이는 그림에서는 Vertex Fetch 모듈로 표시
5.데이터를 가져온 후, SM에서 32개의 스레드로 구성된 스레드 묶음(Warp)을 스케줄링하여 정점 데이터 처리를 시작.
Warp는 단일 명령 다중 스레드(SIMT, SIMD 단일 명령 다중 데이터의 업그레이드)의 구현으로, 32개의 스레드가 동일한 명령을 실행하지만 스레드 데이터는 다름
이러한 방식의 장점은 하나의 Warp가 명령을 디코딩하고 실행하는 데 하나의 논리 회로만 필요하므로 칩을 더 작고 빠르게 만들 수 있다는 것.
이러한 방식이 가능한 이유는 GPU가 처리해야 하는 작업이 자연스럽게 병렬화되어 있기 때문.
6.SM의 Warp 스케줄러는 순서대로 명령을 전체 Warp에 배포하며, 단일 Warp 내의 스레드는 잠금 단계(lock-step)로 각자의 명령을 실행.
스레드가 비활성화된 경우에도 마스킹됩니다(be masked out). 마스킹되는 이유는 여러 가지가 존재하는데,
7.내가 참고했던 문서에서는 현재 명령이 if(true) 분기이지만 현재 스레드의 데이터 조건이 false이거나, 반복 횟수가 다른 경우(예: for 반복 횟수 n이 상수가 아니거나 break로 인해 다른 스레드가 계속 진행 중인 경우)인데, 이때문에 shader 내의 분기는 시간 소모를 크게 증가시킴
하나의 Warp 내의 분기는 32개의 스레드가 모두 if 또는 else 내부로 들어가지 않는 한, 모든 분기를 한 번씩 실행하는 것과 같음.
스레드는 독립적으로 명령을 실행할 수 없고 Warp 단위로 실행되며, 이 Warp들 간에서만 독립적.
8.Warp 내의 명령은 한 번에 완료될 수도 있고, 여러 번 스케줄링될 수도 있음
일반적으로 SM 내의 LD/ST(로드/저장) 유닛 수는 기본 수학 연산 유닛보다 훨씬 적음.
9.일부 명령은 다른 명령보다 더 오랜 시간이 걸리는 경우, 특히 메모리 로드의 경우, Warp 스케줄러는 단순히 메모리 대기 중이 아닌 다른 Warp로 전환할 수 있음. 이것이 GPU가 메모리 읽기 지연을 극복하는 핵심.
이건 단순화하자면, 활성 스레드 그룹을 전환하는 것이긴함.
이러한 전환을 매우 빠르게 하기 위해 스케줄러가 관리하는 모든 Warp는 레지스터 파일에 자신의 레지스터를 가지고 있습니다. 여기서 문제가 발생하는데.
shader가 더 많은 레지스터를 필요로 할수록 Warp에 남는 공간이 줄어들고, 더 적은 Warp가 생성됨.
이 경우 메모리 지연이 발생하면 단순히 대기하게 되고, 실행할 수 있는 Warp가 없게 된다.

10. Wrap가 버텍스 쉐이더에 대해서 모든 명령을 처리하면, 뷰포트 변환 모듈에서 작업 결과를 처리하고, 삼각형으로 만든 다음 래스터화(느그들이 그래픽스에서 지겹도록 배우는 그거 맞음.)를 준비하며, GPU는 버텍스 쉐이더 및 픽셀 쉐이더 데이터 통신을 위한 L1 및 L2 캐쉬를 사용함.

11. 삼각형은 분할되어, 여러 GPC에 나누어서 재 할당되고, 삼각형은 범위에 따라 할당될 래스터 엔진(Raster Engines)이 결정됨.
각 래스터 엔진은 하나이상의 화면 타일을 커버하고, 이는 삼각형 렌더링이 하나 이상의 타일에 할당되는 것에 동일함.
즉, 픽셀 단계에서 삼각형 단위의 분할이 화면의 픽셀 단위로 변환되는 것.

12. SM의 Arrtibue Setup은 Vertex-Shader에서 온 데이터가 보간 된 후, Pixel-shader에서 읽을 수 있도록 보장하는 것을 말함
13. GPC의 래스터엔진(raster engines)은 이렇게 만들어진 삼각형에서 작동하고, 이러한 삼각형의 픽셀정보를 생성함
(이때 클리핑, 백 페이스 컬링, Z 컬링을 처리함)
(그래픽스 기초만 알아도 이게 뭘 의미하는지 알테니까 더 설명 안함)
14. 32개의 픽셀 스레드는 한 그룹으로 나뉘거나, 8개의 2x2 픽셀 블록으로 나뉨. 이는 픽셀 쉐이더의 최소 작업단위
이 픽셀 스레드 내에서 삼각형에 의해 커버되지 않는 경우 마스킹되고, SM의 Wrap 스케쥴러는 픽셀 쉐이더의 작업을 관리함.
15. 그리고 일반적인 Vertex shader의 동일한 작동이, 픽셀 쉐이더 스레드에서 실행됨
픽셀내의 값을 성능 소모 없이 얻을 수 있기때문에 lock step 실행이 편리함.

16.마지막으로, 이제 픽셀 셰이더가 색상과 깊이 값의 계산을 완료함
이 시점에서 우리는 삼각형의 원래 API 순서를 고려해야 하며, 데이터를 ROP(Render Output Unit, 렌더링 출력 유닛)로 이동시킴.
ROP 내부에는 많은 ROP 유닛이 있으며, ROP 유닛에서 깊이 테스트와 framebuffer의 혼합을 처리함
깊이와 색상의 설정은 초기 작업이어야함. 그렇지 않으면 두 개의 다른 삼각형이 동일한 픽셀 지점에서 충돌과 오류가 발생할 수 있음.
참고로 우리가 그래픽스에서 배우는 것은
UV 매핑은 12번 문항부터 시작임.
즉 UV 매핑은 3D 모델의 표면에 2D 텍스쳐 이미지를 적용하기 위한 과정인데, 주로 Attribute Setup 단계에서 처리됨
그리고 13번에서 래스터 엔진에서 작업을 하는게, 일반적으로 보가된 UV 좌표를 기반으로 픽셀 쉐이더가 텍스쳐를 샘플링하여 최종 픽셀 색상을 계산함.
참고로 삼각형 내부 픽셀의 정점 속성 보간(interpolation)의 경우 5~7번에서 이뤄지고,
12번때 보간된 좌표가 pixel shader로 전달될때, 값이 전달됨. 이는 텍스쳐 매핑의 정확성을 보장하고 이후 래스터화는 13번임.
즉 우리가 흔히 그래픽스에서 배우는 단계는 11~13번의 단계라고 할 수 있음.
(래스터화는 3D 삼각형을 2D 픽셀 그리드로 변환하는 것을 말함)
누가 문제 삼은 부분이 있는데 뎁스값은 어디냐라는 거에 대해서
뎁스값은
Attribute Setup에서 매핑 정확성 보장할때, 이때 뎁스값도 픽셀 쉐이더에 전달되는거지. 애초에 클리핑, 백 페이스 컬링, Z컬링 처리하려면 뎁스값이 필요하고, 이때 ROP로 전달됨
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.