Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

codingfarm

30. 계산 셰이더(Compute Shader) - 작성중 본문

computer graphics/DirectX12

30. 계산 셰이더(Compute Shader) - 작성중

scarecrow1992 2021. 10. 17. 15:29

0. GPGPU(범용 GPU, General Purpose GPU)

  • 정의 : 대규모 병렬 처리에 적합한 GPU를 비 그래픽 분야에 응용하는것
  • 장점 : 많은양의 원소에 비슷한 연산을 병렬적으로 처리하는데 적합
    • ex : 화면에 그려지는 픽셀 단편(pixel fragment), 파티클 시스템(particle system)
  • 단점 : 그래픽 연산과는 달리 GPU의 연산 결과를 다시 CPU로 보내야함
    • GPU를 통한 연산 속도가 단점을 충분히 보완

 

다중처리기(Multiprocessor)

  • GPU의 병렬처리를 수행하기 위한 장치
  • 다중처리기는 하나의 스레드를 수행하기 위한 CUDA 코어를 32개 가진다.
    • NVIDIA의 Fermi 아키텍처는 다중처리기를 16개 까지 지원한다.
    • 즉, 최대 512개의 CUDA 코어를 지원한다.

 

1. 계산셰이더(Compute Shader)

  • D3D가 제공하는 program 가능 셰이더 중 하나
  • rendering pipeline 외부에 존재한다.
    • 화면에 아무것도 그리지 않고 응용 프로그램이 GPU에 직접 접근하게 해준다.
  • GPU 자원일 직접 read/write 가능
  • 자료병렬적 알고리즘의 구현에 용이
  • 출력을 다른 shader의 입력에 묶을 수 있다.

 

2. 스레드와 스레드 그룹

GPU 프로그래밍에서는 작업을 스레드 단위로 수행한다.

스레드 그룹 : 다수의 스레드의 묶음

스레드 그룹들로 하나의 격자(grid)를 형성한다.

[3 $\times$ 2 격자 형태로 배치된 스레드 그룹들. 각 그룹은 8 $times$ 8 개의 스레드로 구성되어있다.]

하나의 스레드 그룹은 하나의 다중처리기에서 실행된다.

앞서, 다중처리기 하나는 CUDA 코어를 32개 지닌다고 하였다. 이는 하나의 다중 처리기가 한번에 맡을 수 있는 스레드의 최대 갯수가 32개라는 뜻이다. 하지만, 정체 현상(stall)을 숨김으로써 보다 나은 성능을 위해선 다중처리기 당 적어도 두개의 스레드 그룹을 두는것이 바람직하다.

각 스레드 그룹에는 그룹의 모든 스레드가 접근할 수 있는 공유 메모리가 주어진다. 이를 통해 한 스레드 그룹안의 슨레드들 사이에서는 스레드 동기화 연산 이 가능하지만, 다른 그룹 사이의 동기화는 불가능하다.

워프 : 하드웨어가 한 그룹의 스레드를 분할하는 단위 (워프당 스레드 32개)

다중처리기는 하나의 워프를 SIMD32 단위로 처리한다 (즉, 32개의 스레드가 동시에 같은 명령을 실행한다)

Direct3D에서 한 스레드 그룹의 크기를 32의 배수로 설정하는것이 바람직하다.

D3D에서 스레드 그룹을 실행할때 사용하는 메서드는 아래와 같다.

1
2
3
4
5
void ID3D12GraphicsCommandList::Dispatch(
  [in] UINT ThreadGroupCountX,
  [in] UINT ThreadGroupCountY,
  [in] UINT ThreadGroupCountZ
);
cs

각 매개변수들을 통해 스레드 그룹들을 3차원 격자 형태로 구성할 수 있다.

 

 3. 계산 셰이더 예제

다음은 크기가 같은 두 텍스처의 합을 구하는 간단한 계산 셰이더 예제 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cbuffer cbSettings
{
    // Compute shader can access values in constant buffers.
};
 
// Data sources and outputs.
Texture2D gInputA;
Texture2D gInputB;
RWTexture2D<float4> gOutput;
 
// The number of threads in the thread group. The threads in a group can
// be arranged in a 1D, 2D, or 3D grid layout.
[numthreads(16161)]
void CS(int3 dispatchThreadID : SV_DispatchThreadID) // Thread ID
{
    // Sum the xyth texels and store the result in the xyth texel of
    // gOutput.
    gOutput[dispatchThreadID.xy] =
        gInputA[dispatchThreadID.xy] +
gInputB[dispatchThreadID.xy];
}
cs

 

하나의 계산 셰이더 프로그램은 다음과 같은 요소들로 구성된다.

  1. 상수 버퍼들을 통한 전역 변수 접근
  2. 입력 자원과 출력 자원
  3. 스레드 그룹의 구성과 스레드 갯수를 지정하는 [numthreads(X, Y, Z)] 특성
  4. 각 스레드에서 실행될 명령들을 담은 계산 셰이더 함수 본문
  5. 스레드 식별을 위한 시스템 값 의미소 매개변수

 

numthreads 특성

스레드 그룹을 형성하기 위한 스레드들의 위상구조(topology)를 구성할 수 있다. 

그룹당 총  스레드 갯수는 반드시 워프 크기(32, NVIDIA 카드) 또는 웨이브 프런트 크기(64, AMD 카드)의 배수여야 한다.

웨이브 프런트 크기의 배수로 설정하면 두 종류의 카드 모두를 만족할 수 있다.

 

 

                                                                                          

 

 

 

 

 

 

 

'computer graphics > DirectX12' 카테고리의 다른 글

29. 스텐실 적용(Stenciling)  (0) 2021.10.03
28. 혼합(Blending) - 작성 중  (0) 2021.09.27
27-1. 텍스처적용 예제 코드  (0) 2021.09.22
27. 텍스처 적용(Texturing)  (0) 2021.09.19
26. 좌표 변환  (0) 2021.08.23
Comments