GPU 의 Warp schduler 를 이해하기 위해
warp 가 어떤 이유로 stall 에 빠지는지 파악 필요
다음과 같은ㅇ 이유로 warp 가 멈춤
- memory dependency stall ( L1TEX / L2 대기 )
- scoreboard dependency stall ( FMA 체인등 )
- IMC stall ( instruction immediate constant miss )
- branch / fech stall
- structural hazard stall
test 를 통해 각각의 stall 을 직접 유발, Nsight Compute 의 메시지 출력 확인
테스트 코드 - Stall 생성 전용 Micro - Kernel, Nsight Compute 결과 분석
(1) mem_stall_kernel - L1TEX / L2 miss stall 유발 (메모리 병목)
__global__
void mem_stall_kernel(const float* __restrict__ in, float* __restrict__ out, int N)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
float acc = 0.f;
// 랜덤 패턴 → L1/L2 miss 증가 → memory stall 강제
for (int i = 0; i < 4096; i++) {
int idx = (tid * 97 + i * 57) & (N - 1);
acc += in[idx];
}
out[tid] = acc;
}
stalled waiting for a scoreboard dependency on L1TEX
IMC miss stall ~ 60~80%
L1/L2 hit rate 낮음
OPT Memory dependency stalls detected.
Consider improving coalescing or reuse.
- 랜덤 패턴 때문에 coalescing 실패
- 대부분의 load 가 L1/L2 miss -> warp 가 L1TEX 응답을 기다리며 tall
- warp 가 issue-ready 상태로 오래 존재하지 못함
(2) dep_stall_kernel -> FMA dependency chain (Scoreboard stall)
__global__
void dep_stall_kernel(const float* __restrict__ in, float* __restrict__ out, int N)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
float acc = in[tid];
// pipeline dependency 강제 → scoreboard stall
for (int i = 0; i < 4096; i++) {
acc = acc * 1.0000001f + 0.0000001f;
}
out[tid] = acc;
}
stalled waiting on a scoreboard dependency
dependency chain detected
Compute Workload Analysis 의 특징
- Executed IPC 낮게 나옴
- Issue Slots Busy 낮음
- FMA pipeline stall 비중이 매우 큼
의미
- FMA 가 previous FMA 결과를 기다림 - scoreboard stall
- 메모리 stall 이 아니므로 L1/L2 metricsc 는 정상
- IPC 가 크게 떨어
(3) mixed_stall_kernel -> 메모리 + 의존성 혼합 stall
__global__
void mixed_stall_kernel(const float* __restrict__ in, float* __restrict__ out, int N)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
float acc = in[tid];
for (int i = 0; i < 4096; i++) {
acc = acc * 1.0000001f + 0.0000001f; // dependency
int idx = (tid * 17 + i * 31) & (N - 1); // random load
acc += in[idx];
}
out[tid] = acc;
}
Memory stall: L1TEX dependency ~40%
Dependency stall: scoreboard ~45%
- 연산 사이에 메모리 load 가 끼어 있어
- dependency chain + 메모리 latency 가 서로 역학적 stall 발생
- 실전에서 타일링이 부재시 가장 흔한 패턴
실험을 통해 얻는 핵심 결론
1) warp stall은 크게 둘이다
① memory stall
- L1TEX/L2 miss
- coalescing 실패
- DRAM latency 노출
② dependency stall
- 연산 파이프라인이 이전 연산 결과를 기다림
- scoreboard dependency
- ILP 부족
이 두 종류가 섞이면 GPU 성능이 가장 빠르게 붕괴한다.
2) GPU 성능 최적화란 = stall을 제거하는 과정
- shared memory tiling → global memory stall 줄임
- L2 reuse 개선 → pass-by-pass 성능 증가
- ILP 증가 (register tiling, loop unroll) → dependency stall 감소
- warp specialization → prefetch warp와 compute warp를 분리
- cp.async → L2→shared load를 overlap하여 latency 제거
- double-buffering → 연산/로드 겹침
3) Nsight Compute는 stall의 원인을 ‘정확히’ 알려준다
본 실험에서는 특히 다음 섹션을 통해 명확하게 확인할 수 있다:
- Warp State Statistics
- Scheduler Statistics
- Memory Workload Analysis
- Source Counters
- L1TEX stall breakdown
이 정보만 보면 kernel이 어느 방향으로 최적화해야 하는지 바로 보인다.
'GPU-KERNEL' 카테고리의 다른 글
| Naive GEMM vs Shared Memory Tiling GEMM Test (0) | 2025.11.30 |
|---|---|
| 최종 도달 목표 (0) | 2025.11.30 |
| Occupancy vs Peformance test ( Block Size Sweep ) (0) | 2025.11.29 |
| Register Pressure test (0) | 2025.11.29 |
| L1 / L2 Cache and Access Locality test (0) | 2025.11.29 |