핵심 정리
| 항목 | 의미 |
|---|---|
| Compute shader | 화면에 직접 그리지 않는 GPU 병렬 계산 shader |
| Dispatch | workgroup 수를 지정해 실행 |
| Workgroup | 함께 스케줄되는 실행 단위 |
| Storage buffer | 읽고 쓰는 대용량 데이터 버퍼 |
| Barrier | 같은 dispatch 안의 메모리 순서 조정 |
CPU dispatch
-> workgroups
-> many shader invocations
-> buffer 또는 texture에 결과 기록
-> 다음 pass에서 사용구조
Compute shader는 vertex shader처럼 정점을 입력으로 받거나 fragment shader처럼 화면 샘플에 묶이지 않습니다. 개발자가 정한 grid 크기만큼 실행되고, 각 invocation은 자신의 index를 기준으로 buffer나 texture를 읽고 씁니다.
dispatch(64, 1, 1)
workgroup_size(256)
-> 최대 64 * 256개의 병렬 작업 후보이 구조는 화면에 그리는 작업보다 데이터 병렬 계산에 잘 맞습니다. particle update, culling, prefix sum, image processing, tiled light list 생성처럼 같은 계산을 많은 원소에 반복하는 작업이 대표적입니다.
그래픽 pass와의 차이
그래픽 pass는 pipeline 상태, vertex input, rasterization, depth/blend 같은 고정 기능 단계와 연결됩니다. Compute pass는 이런 단계 없이 thread-like invocation이 직접 메모리에 접근합니다. 그래서 더 자유롭지만, 메모리 충돌과 동기화 책임도 커집니다.
graphics pass
-> geometry를 화면 샘플로 변환
compute pass
-> 데이터 배열을 병렬로 갱신선택 기준
| 상황 | 판단 |
|---|---|
| 화면 픽셀마다 색을 계산 | fragment shader |
| 정점 위치를 변환 | vertex shader |
| 큰 배열을 병렬 갱신 | compute shader |
| 렌더링 전 객체 후보를 줄임 | compute culling |
| CPU에서 반복문이 병목 | GPU 병렬화 검토 |
| 작업량이 작고 readback 필요 | CPU가 더 단순할 수 있음 |
Compute shader는 GPU에서 끝나는 데이터 흐름에 특히 적합합니다. 계산 결과를 바로 CPU로 읽어 오면 동기화와 readback 비용 때문에 장점이 줄어듭니다.
주의할 점
Compute shader는 자동으로 빠른 선택지가 아닙니다. 메모리 접근 패턴이 흩어져 있거나 thread 간 충돌이 많으면 ALU보다 bandwidth와 synchronization이 병목이 됩니다.
또 dispatch 결과를 다음 render pass에서 읽으려면 resource state, barrier, pass 의존성을 명확히 관리해야 합니다. 결과가 가끔 깨지는 문제는 계산식보다 동기화 누락에서 나오는 경우가 많습니다.
참고 링크
1 sources