SISD(Single Instruction Single Date)
ㄴ하나의 명령어로 하나의 데이터만 처리한다.
SIMD(Single Instruction Multiple Data)
ㄴ하나의 명령어로 여러 데이터를 동시에 처리한다.
C언어의 코드로 보면 다음과 같다.
add함수의 연산하는 구간이 한번에 같은 더하기 연산이 처리된 것을 알 수 있다.
Shader에서 Vector3+Vector3 연산은 SIMD 방식으로
각 원소끼리 한번에 더하는 연산인 것을 알 수 있다.
조금더 나아가서 GPU의 연산 단위를 알아보자.
GPU 작업 단위 계층 Thread (쓰레드)가
셰이더의 가장 작은 연산 단위.
픽셀 셰이더라면 보통 픽셀 1개 = 쓰레드 1개.
버텍스 셰이더라면 버텍스 1개 = 쓰레드 1개.
즉, "1작업"이란 보통 이 단위를 가리킵니다.
NVIDIA: 32 threads = 1 warp
AMD: 64 threads = 1 wavefront
쓰레드 하나만 실행하는 게 아니라, 하드웨어가 내부적으로 최소 실행 단위를 warp 단위로 처리하는 것.
즉, 쓰레드 하나를 실행시키더라도 내부적으로는 warp 전체가 실행 준비 상태가 됩니다.
텍스처 512×512 = 총 262,144 픽셀, GPU에서 픽셀 하나 = 스레드 하나
그래서 262,144 스레드가 필요합니다.
warp = 32개 스레드입니다. 따라서 262,144 ÷ 32 = 8,192 warp 필요합니다.
이렇기 때문에 sampler를 통해서 작업하는게 어느정도 비용이 드는 과정이기도하다.
효율적인 연산 방식인 SIMD를 사용못할 상황도 존재합니다.
그 구조를 사용하지 않도록 주의할 필요가 있습니다.
바로 분기처리가 들어가는 구간입니다.
if (x > 0.5) {
color = red;
} else {
color = blue;
}
warp 안에 어떤 스레드는 true, 어떤 스레드는 false일 수 있습니다.
GPU는 분기별로 나눠서 순차 실행해야 합니다.
1. true인 스레드들만 활성화해서 red, 2. false인 스레드들만 활성화해서 blue
즉, 병렬 실행이 직렬화됨 → 성능 하락됩니다.
원래는 warp 전체가 "한 명령어"를 동시에 실행해야 SIMD인데,
분기문 때문에 warp 내부가 갈라지면,
실제로는 각 분기마다 같은 명령어를 실행하지만,
스레드가 절반만 켜졌다 꺼졌다 반복하는 상황이 도래됩니다.
이를 branch divergence (분기 다이버전스) 라고 부르고,
우리는 분기가 없는 구조인 branchless라고 부르는 구조로 가야합니다.
그렇기에 수학적인 방식으로 분기처리를 대신하는 구조로 발전하게 되었습니다.
step, smoothstep, lerp 등이 그 예시 중에 하나이고,
최근에 원핫 마스크라고 RGBA를 분리하는 수식 구조를 소개하는 블로그를 발견해서 여기에 추가합니다.
https://techartnomad.tistory.com/568
2편은 위 블로그 내용을 공부해서 이해한 과정들을 담은 예정입니다.
'Shader' 카테고리의 다른 글
Shader와 SIMD에 대해서 - 2편 (1) | 2025.09.27 |
---|---|
셰이더 공부하기 - Random (0) | 2025.09.08 |
셰이더 공부하기 - Pattern (0) | 2025.09.08 |
셰이더 공부 - 2D Matrix (0) | 2025.09.08 |
셰이더 공부하기 - 도형그리기 (0) | 2025.09.08 |