커널 최적화(kernel optimization) 의 핵심은 **“커널 내부(intra-kernel) 병렬성과 데이터 이동 효율”**을 극한으로 끌어올리는 것이지,
다중 스트림(inter-kernel concurrency) 은 커널 밖(runtime-level scheduling) 에서 처리하는 보조적인 레이어입니다.
현재 구현 상황은 단일 스트림 상에서 모델의 구현, 실행, 이로 인해 불변, 결정성 ( deterministic ) 이 보장되었음,
그렇다면 다중 스트림 상황은 언제 필요할까? 이게 GPU 의 병렬 연산과는 차이가 뭘까? 에서 시작,
먼저 GPU 의 실행 모델을 위계적으로 구분해 정리
CPU(Host)
└─ Stream(명령 큐)
└─ Kernel Launch (<<<grid, block, sharedMem, stream>>>)
└─ Grid = Blocks 집합
└─ Block(CTA) = Threads 집합 + Shared Memory
└─ Threads (Warp=32개 단위로 실행)
GPU 하드웨어
└─ 여러 SM(Streaming Multiprocessor)
├─ Warp Schedulers, Registers, Shared Mem, L1
└─ L2 + Global Memory(드램) 공유
Stream, 스트림 - 명령 큐 & 커널 간 동시성
GPU 에 던지는 비동기 명령 큐, 서로 다른 스트림끼리는 동시 실행 가능
Kernel, 커널 - GPU 에서 실행되는 함수
실제 계산 로직, 타일링 / 메모리 접근 / epilogue 등 커널 내부 최적화의 대상 : 커널 내부 병렬화가 성능의 80 ~ 90 %
Grid - 커널의 전체 작업 공간
Block 들의 집합, 입력 전체를 타일로 나눠 Block 에 배분, 입력 크기에 맞춘 타일링 전략
Block - 협동 단위 + Shared Memory
여러 Thread 의 묶음, 공유 자원, Shared Memory, Register,
Thread - 최소 실행 단위
실제 연산 수행자, Register - Shared - L1/L2 - Global 순으로 빠름
Warp - 하드웨어 실행 묶음
32thread 가 lockstep 으로 같은 명령 실행
SM (Streaming Multiprocessor) - 실행 엔진
Block 을 받아 Warp 단위로 스케줄
메모리 계층 - 속도 : 범위 trade-off
계층 범위 특징 / 팁
| Register | Thread | 최상속도, 레지스터 압박이 크면 occupancy↓ |
| Shared Mem | Block | 타일 재사용, 뱅크 충돌 회피 |
| L1 | SM 로컬 | 자동 캐시 |
| L2 | GPU 전역 | 모든 SM 공유, 캐시 오염 주의 |
| Global | GPU 전체 | 가장 느림, coalesced 접근 필수 |
| Constant/Texture | 읽기 최적 | 브로드캐스트/샘플링 특화 |
흔한 오해/함정 (Pitfalls)
- “다중 스트림 = 항상 더 빠름” → ❌
자원 포화 시 오히려 느림. 단일 스트림 포화가 우선. - “타일을 스트림으로 쪼개자” → ❌
타일링은 커널 내부 병렬성. 스트림으로 흉내 내면 런치/캐시 오버헤드↑.
언제 무엇을 건드릴까 (추론 최적화 실전)
- 먼저 커널 내부부터
- 큰 GEMM/Conv: 라이브러리 최적경로 또는 전용 커널(Flash-Attn 등).
- 메모리: coalesced 접근, vectorized load/store, 타일 재사용.
- Epilogue/후처리 fusion으로 커널 수/메모리 왕복 최소화.
- 그 다음 런치/스케줄
- CUDA Graph로 런치 오버헤드 제거.
- 기본 단일 스트림으로 포화 확인 → 남는 자원 있을 때만 보조 스트림.
- 복사 오버랩: 입력 프리패치/출력 비동기 복사.
- 동시 요청/마이크로배치
- 작은 요청 다수 → 여러 그래프(exec)를 여러 스트림에 분산.
- 무거운 branch/GEMM끼리 중첩은 지양(리소스 충돌).
- 검증
- Nsight Systems: 스트림/복사 실제 오버랩인지 눈으로 확인(NVTX 태깅).
- Nsight Compute: roofline, warp stall 원인, L2/DRAM 스루풋.
'dev_AI_framework' 카테고리의 다른 글
| 새로운 스텝, 국소적인 각 부분에서 전체까지, 검증의 과정이 필요 (0) | 2025.11.14 |
|---|---|
| dropout 의 scaling 과 constexpr 을 통한 compile 내 최적화 - 결정론적이려면 어떻게 해야 하는지 (0) | 2025.11.13 |
| ai_shim.hpp 의 수정 이후 오류 발생, 해결 과정 - activation function 에 의한 save_z 조건의 규칙을 좀 더 세분화해야겠다. (0) | 2025.11.10 |
| 백엔드의 standalone ops 체제로 전환 ( ai_shim 의 사용 ) (0) | 2025.11.10 |
| 현재 상황 정리, 앞으로 뭘 어떻게 해야 할까 (0) | 2025.11.06 |