๐ NVIDIA ํ๋กํ์ผ๋ง ๊ธฐ์ด
๊ฐ์
์ง๊ธ๊น์ง GPU ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ์ด์ ๊ณ ๊ธ ํจํด์ ๋ฐฐ์ ์ต๋๋ค. Part II์์๋ compute-sanitizer์ cuda-gdb๋ฅผ ์ฌ์ฉํ ์ ํ์ฑ ๋๋ฒ๊น
๊ธฐ๋ฒ์, ๋ค๋ฅธ ํํธ์์๋ ์ํ ํ๋ก๊ทธ๋๋ฐ, ๋ฉ๋ชจ๋ฆฌ ์์คํ
, ๋ธ๋ก ๋ ๋ฒจ ์ฐ์ฐ ๋ฑ ๋ค์ํ GPU ๊ธฐ๋ฅ์ ๋ค๋ค์ต๋๋ค. ์ปค๋์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๊ธด ํฉ๋๋ค - ํ์ง๋ง ๋น ๋ฅด๊ธฐ๋ ํ ๊น์?
์ด ํํ ๋ฆฌ์ผ์ CUDA Best Practices Guide์์ ๊ถ์ฅํ๋ NVIDIA ํ๋กํ์ผ๋ง ๋ฐฉ๋ฒ๋ก ์ ๋ฐ๋ฆ ๋๋ค.
ํต์ฌ ํต์ฐฐ: ์ฌ๋ฐ๋ฅธ ์ปค๋์ด๋ผ๋ ์ต์ ์ ์ฑ๋ฅ๋ณด๋ค ์์ญ ๋ฐฐ๋ ๋๋ฆด ์ ์์ต๋๋ค. ํ๋กํ์ผ๋ง์ ๋์ํ๋ ์ฝ๋์ ๊ณ ์ฑ๋ฅ ์ฝ๋ ์ฌ์ด์ ๊ฒฉ์ฐจ๋ฅผ ์ขํ๋๋ค.
ํ๋กํ์ผ๋ง ๋๊ตฌ ๋ชจ์
pixi๋ฅผ ํตํด cuda-toolkit์ด ์ค์น๋์ด ์์ผ๋ฏ๋ก, NVIDIA์ ์ ๋ฌธ ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค:
NSight Systems (nsys) - โ์ ์ฒด ๊ทธ๋ฆผโ ๋๊ตฌ
์ฉ๋: ์์คํ ์ ์ฒด ์ฑ๋ฅ ๋ถ์ (NSight Systems ๋ฌธ์)
- CPU-GPU ์ํธ์์ฉ์ ํ์๋ผ์ธ ๋ทฐ
- ๋ฉ๋ชจ๋ฆฌ ์ ์ก ๋ณ๋ชฉ
- ์ปค๋ ์คํ ์ค๋ฒํค๋
- ๋ฉํฐ GPU ์กฐ์จ
- API ํธ์ถ ์ถ์
์ฌ์ฉ ๊ฐ๋ฅํ ์ธํฐํ์ด์ค: ์ปค๋งจ๋๋ผ์ธ (nsys) ๋ฐ GUI (nsys-ui)
์ฌ์ฉ ์์ :
- ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ํ๋ฆ ํ์
- CPU-GPU ๋๊ธฐํ ๋ฌธ์ ์๋ณ
- ๋ฉ๋ชจ๋ฆฌ ์ ์ก ํจํด ๋ถ์
- ์ปค๋ ์คํ ๋ณ๋ชฉ ๋ฐ๊ฒฌ
# ๋์๋ง ๋ณด๊ธฐ
pixi run nsys --help
# ๊ธฐ๋ณธ ์์คํ
์ ์ฒด ํ๋กํ์ผ๋ง
pixi run nsys profile --trace=cuda,nvtx --output=timeline mojo your_program.mojo
# ๋ํํ ๋ถ์
pixi run nsys stats --force-export=true timeline.nsys-rep
NSight Compute (ncu) - โ์ปค๋ ์ฌ์ธต ๋ถ์โ ๋๊ตฌ
์ฉ๋: ์์ธํ ๋จ์ผ ์ปค๋ ์ฑ๋ฅ ๋ถ์ (NSight Compute ๋ฌธ์)
- ๋ฃจํ๋ผ์ธ ๋ชจ๋ธ ๋ถ์
- ๋ฉ๋ชจ๋ฆฌ ๊ณ์ธต ๊ตฌ์กฐ ํ์ฉ๋
- ์ํ ์คํ ํจ์จ
- ๋ ์ง์คํฐ/๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
- ์ฐ์ฐ ์ ๋ ํ์ฉ๋
์ฌ์ฉ ๊ฐ๋ฅํ ์ธํฐํ์ด์ค: ์ปค๋งจ๋๋ผ์ธ (ncu) ๋ฐ GUI (ncu-ui)
์ฌ์ฉ ์์ :
- ํน์ ์ปค๋ ์ฑ๋ฅ ์ต์ ํ
- ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด ํ์
- ์ฐ์ฐ ๋ฐ์ด๋ vs ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋ ์ปค๋ ๋ถ์
- ์ํ ๋ถ๊ธฐ ๋ฌธ์ ์๋ณ
# ๋์๋ง ๋ณด๊ธฐ
pixi run ncu --help
# ์์ธ ์ปค๋ ํ๋กํ์ผ๋ง
pixi run ncu --set full --output kernel_profile mojo your_program.mojo
# ํน์ ์ปค๋์ ์ง์ค
pixi run ncu --kernel-name regex:your_kernel_name mojo your_program.mojo
๋๊ตฌ ์ ํ ์์ฌ๊ฒฐ์ ํธ๋ฆฌ
์ฑ๋ฅ ๋ฌธ์ ๋ฐ์
|
v
์ด๋ค ์ปค๋์ธ์ง ์๋๊ฐ?
| |
์๋์ค ์
| |
v v
NSight ์ปค๋ ๊ณ ์ ์ ๋ฌธ์ ์ธ๊ฐ?
Systems | |
| ์๋์ค ์
v | |
ํ์๋ผ์ธ | v
๋ถ์ <------+ NSight Compute
|
v
์ปค๋ ์ฌ์ธต ๋ถ์
๋น ๋ฅธ ์์ฌ๊ฒฐ์ ๊ฐ์ด๋:
- ๋ณ๋ชฉ์ด ์ด๋์ธ์ง ๋ชจ๋ฅด๊ฒ ์ผ๋ฉด NSight Systems (
nsys)๋ถํฐ ์์ - ์ต์ ํํ ์ปค๋์ ์ ํํ ์๋ฉด NSight Compute (
ncu) ์ฌ์ฉ - ์ข ํฉ์ ์ธ ๋ถ์์ด ํ์ํ๋ฉด ๋ ๋ค ์ฌ์ฉ (์ผ๋ฐ์ ์ธ ์ํฌํ๋ก์ฐ)
์ค์ต: NSight Systems๋ก ์์คํ ์ ์ฒด ํ๋กํ์ผ๋ง
Puzzle 16์ ํ๋ ฌ ๊ณฑ์ ๊ตฌํ๋ค์ ํ๋กํ์ผ๋งํ์ฌ ์ฑ๋ฅ ์ฐจ์ด๋ฅผ ํ์ ํด ๋ด ์๋ค.
GUI ์ฐธ๊ณ : NSight Systems์ Compute GUI (
nsys-ui,ncu-ui)๋ ๋์คํ๋ ์ด์ OpenGL ์ง์์ด ํ์ํฉ๋๋ค. X11 ํฌ์๋ฉ์ด ์๋ ํค๋๋ฆฌ์ค ์๋ฒ๋ ์๊ฒฉ ์์คํ ์์๋ ์ปค๋งจ๋๋ผ์ธ ๋ฒ์ (nsys,ncu)์ ์ฌ์ฉํ์ฌnsys stats์ncu --import --page details๋ก ํ ์คํธ ๊ธฐ๋ฐ ๋ถ์์ ์ํํ์ธ์..nsys-rep์.ncu-repํ์ผ์ ๋ก์ปฌ ๋จธ์ ์ผ๋ก ์ ์กํ์ฌ GUI๋ก ๋ถ์ํ ์๋ ์์ต๋๋ค.
Step 1: ํ๋กํ์ผ๋ง์ ์ํ ์ฝ๋ ์ค๋น
์ค์: ์ ํํ ํ๋กํ์ผ๋ง์ ์ํด ์ต์ ํ๋ฅผ ์ ์งํ๋ฉด์ ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ ๋น๋ํฉ๋๋ค:
pixi shell -e nvidia
# ์ต์ ํ๋ฅผ ์ ์งํ๋ฉด์ ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด ํฌํจ ๋น๋ (ํฌ๊ด์ ์ธ ์์ค ๋งคํ์ฉ)
mojo build --debug-level=full solutions/p16/p16.mojo -o solutions/p16/p16_optimized
# ์ต์ ํ ๋น๋ ํ
์คํธ
./solutions/p16/p16_optimized --naive
์ด๊ฒ์ด ์ค์ํ ์ด์ :
- ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด: ํ๋กํ์ผ๋ฌ๋ฅผ ์ํ ์์ ํ ์ฌ๋ณผ ํ ์ด๋ธ, ๋ณ์๋ช , ์์ค ๋ผ์ธ ๋งคํ ์ ๊ณต
- ํฌ๊ด์ ๋ถ์: NSight ๋๊ตฌ๊ฐ ์ฑ๋ฅ ๋ฐ์ดํฐ๋ฅผ ํน์ ์ฝ๋ ์์น์ ์ฐ๊ฒฐ ๊ฐ๋ฅ
- ์ต์ ํ ์ ์ง: ํ๋ก๋์ ๋น๋์ ์ผ์นํ๋ ํ์ค์ ์ธ ์ฑ๋ฅ ์ธก์ ๋ณด์ฅ
Step 2: ์์คํ ์ ์ฒด ํ๋กํ์ผ ์์ง
# ํฌ๊ด์ ์ถ์ ์ผ๋ก ์ต์ ํ ๋น๋ ํ๋กํ์ผ๋ง
nsys profile \
--trace=cuda,nvtx \
--output=matmul_naive \
--force-overwrite=true \
./solutions/p16/p16_optimized --naive
๋ช ๋ น์ด ๋ถ์:
--trace=cuda,nvtx: CUDA API ํธ์ถ ๋ฐ ์ปค์คํ ์ด๋ ธํ ์ด์ ์บก์ฒ--output=matmul_naive: ํ๋กํ์ผ์matmul_naive.nsys-rep๋ก ์ ์ฅ--force-overwrite=true: ๊ธฐ์กด ํ๋กํ์ผ ๋ฎ์ด์ฐ๊ธฐ- ๋ง์ง๋ง ์ธ์: Mojo ํ๋ก๊ทธ๋จ
Step 3: ํ์๋ผ์ธ ๋ถ์
# ํ
์คํธ ๊ธฐ๋ฐ ํต๊ณ ์์ฑ
nsys stats --force-export=true matmul_naive.nsys-rep
# ์ฃผ์ ์งํ ํ์ธ:
# - GPU ํ์ฉ๋ฅ
# - ๋ฉ๋ชจ๋ฆฌ ์ ์ก ์๊ฐ
# - ์ปค๋ ์คํ ์๊ฐ
# - CPU-GPU ๋๊ธฐํ ๊ฐ๊ฒฉ
ํ์ธํ ์ ์๋ ๊ฒฐ๊ณผ (2ร2 ํ๋ ฌ ๊ณฑ์ ์ ์ค์ ์ถ๋ ฅ):
** CUDA API Summary (cuda_api_sum):
Time (%) Total Time (ns) Num Calls Avg (ns) Med (ns) Min (ns) Max (ns) StdDev (ns) Name
-------- --------------- --------- --------- -------- -------- -------- ----------- --------------------
81.9 8617962 3 2872654.0 2460.0 1040 8614462 4972551.6 cuMemAllocAsync
15.1 1587808 4 396952.0 5965.5 3810 1572067 783412.3 cuMemAllocHost_v2
0.6 67152 1 67152.0 67152.0 67152 67152 0.0 cuModuleLoadDataEx
0.4 44961 1 44961.0 44961.0 44961 44961 0.0 cuLaunchKernelEx
** CUDA GPU Kernel Summary (cuda_gpu_kern_sum):
Time (%) Total Time (ns) Instances Avg (ns) Med (ns) Min (ns) Max (ns) StdDev (ns) Name
-------- --------------- --------- -------- -------- -------- -------- ----------- ----------------------------------------
100.0 1920 1 1920.0 1920.0 1920 1920 0.0 p16_naive_matmul_Layout_Int6A6AcB6A6AsA6A6A
** CUDA GPU MemOps Summary (by Time) (cuda_gpu_mem_time_sum):
Time (%) Total Time (ns) Count Avg (ns) Med (ns) Min (ns) Max (ns) StdDev (ns) Operation
-------- --------------- ----- -------- -------- -------- -------- ----------- ----------------------------
49.4 4224 3 1408.0 1440.0 1312 1472 84.7 [CUDA memcpy Device-to-Host]
36.0 3072 4 768.0 528.0 416 1600 561.0 [CUDA memset]
14.6 1248 3 416.0 416.0 416 416 0.0 [CUDA memcpy Host-to-Device]
์ฃผ์ ์ฑ๋ฅ ํต์ฐฐ:
- ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ด ์ง๋ฐฐ์ : ์ ์ฒด ์๊ฐ์ 81.9%๊ฐ
cuMemAllocAsync์ ์๋น - ์ปค๋์ ๋ฒ๊ฐ์ฒ๋ผ ๋น ๋ฆ: ์คํ ์๊ฐ 1,920 ns (0.000001920์ด)์ ๋ถ๊ณผ
- ๋ฉ๋ชจ๋ฆฌ ์ ์ก ๋ด์ญ: 49.4% DeviceโHost, 36.0% memset, 14.6% HostโDevice
- ์์ฃผ ์์ ๋ฐ์ดํฐ: ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์ฐ์ฐ์ด 0.001 MB ๋ฏธ๋ง (float32 4๊ฐ = 16๋ฐ์ดํธ)
Step 4: ๊ตฌํ ๋น๊ต
๋ค๋ฅธ ๋ฒ์ ๋ค์ ํ๋กํ์ผ๋งํ๊ณ ๋น๊ตํฉ๋๋ค:
# pixi shell ์ํ๋ฅผ ์ ์งํ์ธ์ `pixi run -e nvidia`
# ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ฒ์ ํ๋กํ์ผ๋ง
nsys profile --trace=cuda,nvtx --force-overwrite=true --output=matmul_shared ./solutions/p16/p16_optimized --single-block
# Tiled ๋ฒ์ ํ๋กํ์ผ๋ง
nsys profile --trace=cuda,nvtx --force-overwrite=true --output=matmul_tiled ./solutions/p16/p16_optimized --tiled
# ๊ด์ฉ์ Tiled ๋ฒ์ ํ๋กํ์ผ๋ง
nsys profile --trace=cuda,nvtx --force-overwrite=true --output=matmul_idiomatic_tiled ./solutions/p16/p16_optimized --idiomatic-tiled
# ๊ฐ ๊ตฌํ์ ๊ฐ๋ณ์ ์ผ๋ก ๋ถ์ (nsys stats๋ ํ ๋ฒ์ ํ๋์ ํ์ผ๋ง ์ฒ๋ฆฌ)
nsys stats --force-export=true matmul_shared.nsys-rep
nsys stats --force-export=true matmul_tiled.nsys-rep
nsys stats --force-export=true matmul_idiomatic_tiled.nsys-rep
๊ฒฐ๊ณผ ๋น๊ต ๋ฐฉ๋ฒ:
- GPU Kernel Summary ํ์ธ - ๊ตฌํ ๊ฐ ์คํ ์๊ฐ ๋น๊ต
- Memory Operations ํ์ธ - ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ํธ๋ํฝ์ ์ค์ด๋์ง ํ์ธ
- API ์ค๋ฒํค๋ ๋น๊ต - ๋ชจ๋ ๋น์ทํ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ํจํด์ ๊ฐ์ ธ์ผ ํจ
์๋ ๋น๊ต ์ํฌํ๋ก์ฐ:
# ๊ฐ ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ์ฌ ๋น๊ต
nsys stats --force-export=true matmul_naive.nsys-rep > naive_stats.txt
nsys stats --force-export=true matmul_shared.nsys-rep > shared_stats.txt
nsys stats --force-export=true matmul_tiled.nsys-rep > tiled_stats.txt
nsys stats --force-export=true matmul_idiomatic_tiled.nsys-rep > idiomatic_tiled_stats.txt
๊ณต์ ํ ๋น๊ต ๊ฒฐ๊ณผ (์ค์ ํ๋กํ์ผ๋ง ์ถ๋ ฅ):
๋น๊ต 1: 2 x 2 ํ๋ ฌ
| ๊ตฌํ | ๋ฉ๋ชจ๋ฆฌ ํ ๋น | ์ปค๋ ์คํ | ์ฑ๋ฅ |
|---|---|---|---|
| Naive | 81.9% cuMemAllocAsync | โ 1,920 ns | ๊ธฐ์ค์ |
Shared (--single-block) | 81.8% cuMemAllocAsync | โ 1,984 ns | +3.3% ๋๋ฆผ |
๋น๊ต 2: 9 x 9 ํ๋ ฌ
| ๊ตฌํ | ๋ฉ๋ชจ๋ฆฌ ํ ๋น | ์ปค๋ ์คํ | ์ฑ๋ฅ |
|---|---|---|---|
| Tiled (์๋) | 81.1% cuMemAllocAsync | โ 2,048 ns | ๊ธฐ์ค์ |
| Idiomatic Tiled | 81.6% cuMemAllocAsync | โ 2,368 ns | +15.6% ๋๋ฆผ |
๊ณต์ ๋น๊ต์์ ์ป์ ํต์ฌ ํต์ฐฐ:
๋ ํ๋ ฌ ํฌ๊ธฐ ๋ชจ๋ GPU ์์ ์๋ ๋๋ฌด ์์!:
- 2ร2 ํ๋ ฌ: 4๊ฐ ์์ - ์์ ํ ์ค๋ฒํค๋๊ฐ ์ง๋ฐฐ
- 9ร9 ํ๋ ฌ: 81๊ฐ ์์ - ์ฌ์ ํ ์ค๋ฒํค๋๊ฐ ์ง๋ฐฐ
- ์ค์ GPU ์ํฌ๋ก๋: ์ฐจ์๋น ์์ฒ~์๋ฐฑ๋ง ๊ฐ ์์
์ด ๊ฒฐ๊ณผ๊ฐ ์ค์ ๋ก ๋ณด์ฌ์ฃผ๋ ๊ฒ:
- ๋ชจ๋ ๋ณํ์ด ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์ง๋ฐฐ๋จ (์๊ฐ์ 81% ์ด์)
- ์ปค๋ ์คํ์ ์๋ฏธ ์์ - ์ค์ ๋น์ฉ์ ๋นํ๋ฉด ๋ฏธ๋ฏธ
- โ์ต์ ํโ๊ฐ ์คํ๋ ค ํด๋ก์ธ ์ ์์: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๊ฐ 3.3%, async_copy๊ฐ 15.6% ์ค๋ฒํค๋ ์ถ๊ฐ
- ์ง์ง ๊ตํ: ์์ ์ํฌ๋ก๋์์๋ ์๊ณ ๋ฆฌ์ฆ ์ ํ์ด ๋ฌด์๋ฏธ - ์ค๋ฒํค๋๊ฐ ๋ชจ๋ ๊ฒ์ ์๋
์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ์ด์ :
- GPU ์ค์ ๋น์ฉ(๋ฉ๋ชจ๋ฆฌ ํ ๋น, ์ปค๋ ์คํ)์ ๋ฌธ์ ํฌ๊ธฐ์ ๊ด๊ณ์์ด ๊ณ ์
- ์์ ๋ฌธ์ ์์๋ ์ด ๊ณ ์ ๋น์ฉ์ด ์ฐ์ฐ ์๊ฐ์ ๋ฌด์ํ๊ฒ ๋ง๋ฆ
- ํฐ ๋ฌธ์ ๋ฅผ ์ํด ์ค๊ณ๋ ์ต์ ํ๊ฐ ์์ ๋ฌธ์ ์์๋ ์ค๋ฒํค๋๊ฐ ๋จ
์ค๋ฌด ํ๋กํ์ผ๋ง ๊ตํ:
- ๋ฌธ์ ํฌ๊ธฐ ๋งฅ๋ฝ์ด ์ค์: 2ร2์ 9ร9 ๋ชจ๋ GPU์๊ฒ๋ ์์
- ๊ณ ์ ๋น์ฉ์ด ์์ ๋ฌธ์ ๋ฅผ ์ง๋ฐฐ: ๋ฉ๋ชจ๋ฆฌ ํ ๋น, ์ปค๋ ์คํ ์ค๋ฒํค๋
- โ์ต์ ํโ๊ฐ ์์ ์ํฌ๋ก๋์ ํด๋ก์ธ ์ ์์: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ, ๋น๋๊ธฐ ์ฐ์ฐ์ด ์ค๋ฒํค๋ ์ถ๊ฐ
- ์์ ๋ฌธ์ ๋ฅผ ์ต์ ํํ์ง ๋ง ๊ฒ: ์ค์ ์ํฌ๋ก๋๋ก ํ์ฅ ๊ฐ๋ฅํ ์๊ณ ๋ฆฌ์ฆ์ ์ง์ค
- ํญ์ ๋ฒค์น๋งํนํ ๊ฒ: โ๋ ์ข์โ ์ฝ๋์ ๋ํ ๊ฐ์ ์ ํํ ํ๋ฆผ
์์ ์ปค๋ ํ๋กํ์ผ๋ง์ ์ดํด: ์ด 2ร2 ํ๋ ฌ ์์ ๋ ์ ํ์ ์ธ ์์ ์ปค๋ ํจํด์ ๋ณด์ฌ์ค๋๋ค:
- ์ค์ ์ฐ์ฐ(ํ๋ ฌ ๊ณฑ์ )์ ๊ทนํ ๋น ๋ฆ (1,920 ns)
- ๋ฉ๋ชจ๋ฆฌ ์ค์ ์ค๋ฒํค๋๊ฐ ์ ์ฒด ์๊ฐ์ ์ง๋ฐฐ (์คํ์ 97% ์ด์)
- ์ด๊ฒ์ด ์ค๋ฌด GPU ์ต์ ํ๊ฐ ๋ค์์ ์ง์คํ๋ ์ด์ ์
๋๋ค:
- ์ฐ์ฐ ์ผ๊ด ์ฒ๋ฆฌ๋ก ์ค์ ๋น์ฉ ๋ถ์ฐ
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฌ์ฉ์ผ๋ก ํ ๋น ์ค๋ฒํค๋ ๊ฐ์
- ์ฐ์ฐ์ด ๋ณ๋ชฉ์ด ๋๋ ๋ ํฐ ๋ฌธ์ ํฌ๊ธฐ
์ค์ต: NSight Compute๋ก ์ปค๋ ์ฌ์ธต ๋ถ์
์ด์ ํน์ ์ปค๋์ ์ฑ๋ฅ ํน์ฑ์ ์ฌ์ธต์ ์ผ๋ก ๋ค์ฌ๋ค๋ด ์๋ค.
Step 1: ํน์ ์ปค๋ ํ๋กํ์ผ๋ง
# ํ์ฑ shell ์ํ์ธ์ง ํ์ธ
pixi shell -e nvidia
# Naive MatMul ์ปค๋์ ์์ธ ํ๋กํ์ผ๋ง (์ต์ ํ ๋น๋ ์ฌ์ฉ)
ncu \
--set full \
-o kernel_analysis \
--force-overwrite \
./solutions/p16/p16_optimized --naive
ํํ ๋ฌธ์ : ๊ถํ ์ค๋ฅ
ERR_NVGPUCTRPERM - The user does not have permission to access NVIDIA GPU Performance Counters์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์๋ํ์ธ์:# NVIDIA ๋๋ผ์ด๋ฒ ์ต์ ์ถ๊ฐ (rmmod๋ณด๋ค ์์ ) echo 'options nvidia "NVreg_RestrictProfilingToAdminUsers=0"' | sudo tee -a /etc/modprobe.d/nvidia-kernel-common.conf # ์ปค๋ ํ๋ผ๋ฏธํฐ ์ค์ sudo sysctl -w kernel.perf_event_paranoid=0 # ์๊ตฌ ์ ์ฉ echo 'kernel.perf_event_paranoid=0' | sudo tee -a /etc/sysctl.conf # ๋๋ผ์ด๋ฒ ๋ณ๊ฒฝ ์ฌํญ ์ ์ฉ์ ์ํด ์ฌ๋ถํ ํ์ sudo reboot # ๊ทธ๋ฐ ๋ค์ ncu ๋ช ๋ น์ ๋ค์ ์คํ ncu \ --set full \ -o kernel_analysis \ --force-overwrite \ ./solutions/p16/p16_optimized --naive
Step 2: ์ฃผ์ ์งํ ๋ถ์
# ์์ธ ๋ณด๊ณ ์ ์์ฑ (์ฌ๋ฐ๋ฅธ ๊ตฌ๋ฌธ)
ncu --import kernel_analysis.ncu-rep --page details
์ค์ NSight Compute ์ถ๋ ฅ (2ร2 Naive MatMul):
GPU Speed Of Light Throughput
----------------------- ----------- ------------
DRAM Frequency Ghz 6.10
SM Frequency Ghz 1.30
Elapsed Cycles cycle 3733
Memory Throughput % 1.02
DRAM Throughput % 0.19
Duration us 2.88
Compute (SM) Throughput % 0.00
----------------------- ----------- ------------
Launch Statistics
-------------------------------- --------------- ---------------
Block Size 9
Grid Size 1
Threads thread 9
Waves Per SM 0.00
-------------------------------- --------------- ---------------
Occupancy
------------------------------- ----------- ------------
Theoretical Occupancy % 33.33
Achieved Occupancy % 2.09
------------------------------- ----------- ------------
์ค์ ๋ฐ์ดํฐ์์ ์ป์ ํต์ฌ ํต์ฐฐ:
์ฑ๋ฅ ๋ถ์ - ๋ํนํ ํ์ค
- Compute Throughput: 0.00% - GPU๊ฐ ์ฐ์ฐ์ ์ผ๋ก ์์ ํ ์ ํด ์ํ
- Memory Throughput: 1.02% - ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์
- Achieved Occupancy: 2.09% - GPU ๋ฅ๋ ฅ์ 2%๋ง ์ฌ์ฉ ์ค
- Grid Size: 1 ๋ธ๋ก - 80๊ฐ ๋ฉํฐํ๋ก์ธ์๋ฅผ ์์ ํ ๋ญ๋น!
์ฑ๋ฅ์ด ์ด๋ ๊ฒ ๋ฎ์ ์ด์
- ์์ ๋ฌธ์ ํฌ๊ธฐ: 2ร2 ํ๋ ฌ = ์ด 4๊ฐ ์์
- ์๋ชป๋ ์คํ ๊ตฌ์ฑ: 1๊ฐ ๋ธ๋ก์ 9๊ฐ ์ค๋ ๋ (32์ ๋ฐฐ์์ฌ์ผ ํจ)
- ์ฌ๊ฐํ ๊ณผ์ ํ์ฉ: SM๋น 0.00 wave (ํจ์จ์ ์ํด ์์ฒ ๊ฐ ํ์)
NSight Compute์ ํต์ฌ ์ต์ ํ ๊ถ๊ณ ์ฌํญ
- โEst. Speedup: 98.75%โ - 80๊ฐ SM์ ๋ชจ๋ ์ฌ์ฉํ๋๋ก ๊ทธ๋ฆฌ๋ ํฌ๊ธฐ ์ฆ๊ฐ
- โEst. Speedup: 71.88%โ - ์ค๋ ๋ ๋ธ๋ก์ 32์ ๋ฐฐ์๋ก ์ฌ์ฉ
- โKernel grid is too smallโ - GPU ํจ์จ์ ์ํด ํจ์ฌ ํฐ ๋ฌธ์ ํ์
Step 3: ํ์ค ์ง์
์ด ํ๋กํ์ผ๋ง ๋ฐ์ดํฐ๊ฐ ์๋ ค์ฃผ๋ ๊ฒ:
- ์์ ๋ฌธ์ ๋ GPU์๊ฒ ๋ : 2ร2 ํ๋ ฌ์ GPU ๋ฆฌ์์ค๋ฅผ ์์ ํ ๋ญ๋น
- ์คํ ๊ตฌ์ฑ์ด ์ค์: ์๋ชป๋ ์ค๋ ๋/๋ธ๋ก ํฌ๊ธฐ๊ฐ ์ฑ๋ฅ์ ์ฃฝ์
- ๊ท๋ชจ๊ฐ ์๊ณ ๋ฆฌ์ฆ๋ณด๋ค ์ค์: ๊ทผ๋ณธ์ ์ผ๋ก ์์ ๋ฌธ์ ๋ ์ด๋ค ์ต์ ํ๋ก๋ ํด๊ฒฐ ๋ถ๊ฐ
- NSight Compute๋ ์ ์งํจ: ์ปค๋ ์ฑ๋ฅ์ด ๋ฎ์ ๋ ๊ทธ๋๋ก ์๋ ค์ค
์ง์ง ๊ตํ:
- ํ ์ด ๋ฌธ์ ๋ฅผ ์ต์ ํํ์ง ๋ง ๊ฒ - ์ค์ GPU ์ํฌ๋ก๋๋ฅผ ๋ํํ์ง ์์
- ํ์ค์ ์ธ ์ํฌ๋ก๋์ ์ง์ค - ์ต์ ํ๊ฐ ์ค์ ๋ก ์๋ฏธ ์๋ 1000ร1000+ ํ๋ ฌ
- ํ๋กํ์ผ๋ง์ผ๋ก ์ต์ ํ๋ฅผ ์๋ด - ๋จ, ์ต์ ํํ ๊ฐ์น๊ฐ ์๋ ๋ฌธ์ ์๋ง
2ร2 ์์ ์ ๊ฒฝ์ฐ: ์ ๊ตํ ์๊ณ ๋ฆฌ์ฆ(๊ณต์ ๋ฉ๋ชจ๋ฆฌ, tiling)์ด ์ด๋ฏธ ์ค๋ฒํค๋๊ฐ ์ง๋ฐฐ์ ์ธ ์ํฌ๋ก๋์ ์ค๋ฒํค๋๋ง ์ถ๊ฐํฉ๋๋ค.
ํ๋กํ์ผ๋ฌ ์ถ๋ ฅ์ ์ฑ๋ฅ ํ์ ์ฒ๋ผ ์ฝ๊ธฐ
์์ฃผ ๋ํ๋๋ ์ฑ๋ฅ ํจํด
ํจํด 1: ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ด๋ ์ปค๋
NSight Systems๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ๊ธด ๋ฉ๋ชจ๋ฆฌ ์ ์ก ์๊ฐ NSight Compute๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ๋์ ๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ๋, ๋ฎ์ ์ฐ์ฐ ํ์ฉ๋ ํด๊ฒฐ์ฑ : ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด ์ต์ ํ, ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ
ํจํด 2: ๋ฎ์ ์ ์ ์จ
NSight Systems๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ์งง์ ์ปค๋ ์คํ๊ณผ ๊ฐ๊ฒฉ NSight Compute๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ์ค์ ์ ์ ์จ์ด ๋ฎ์ ํด๊ฒฐ์ฑ : ๋ ์ง์คํฐ ์ฌ์ฉ๋ ์ค์ด๊ธฐ, ๋ธ๋ก ํฌ๊ธฐ ์ต์ ํ
ํจํด 3: ์ํ ๋ถ๊ธฐ
NSight Systems๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ๋ถ๊ท์นํ ์ปค๋ ์คํ ํจํด NSight Compute๊ฐ ๋ณด์ฌ์ฃผ๋ ๊ฒ: ๋ฎ์ ์ํ ์คํ ํจ์จ ํด๊ฒฐ์ฑ : ์กฐ๊ฑด ๋ถ๊ธฐ ์ต์ํ, ์๊ณ ๋ฆฌ์ฆ ์ฌ๊ตฌ์ฑ
ํ๋กํ์ผ๋ง ํ์ ์ํฌํ๋ก์ฐ
์ฑ๋ฅ ๋ฌธ์ ๋ฐ์
|
v
NSight Systems: ์ ์ฒด ๊ทธ๋ฆผ
|
v
GPU๋ฅผ ์ ํ์ฉํ๊ณ ์๋๊ฐ?
| |
์๋์ค ์
| |
v v
CPU-GPU NSight Compute: ์ปค๋ ์์ธ
ํ์ดํ๋ผ์ธ |
์์ v
๋ฉ๋ชจ๋ฆฌ ๋๋ ์ฐ์ฐ ๋ฐ์ด๋์ธ๊ฐ?
| | |
๋ฉ๋ชจ๋ฆฌ ์ฐ์ฐ ๋ ๋ค ์๋
| | |
v v v
๋ฉ๋ชจ๋ฆฌ ์ฐ์ ์ ์ ์จ
์ ๊ทผ ์ต์ ํ ํ์ธ
์ต์ ํ
ํ๋กํ์ผ๋ง ๋ชจ๋ฒ ์ฌ๋ก
ํฌ๊ด์ ์ธ ํ๋กํ์ผ๋ง ์ง์นจ์ Best Practices Guide - Performance Metrics๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์ด๋ ๊ฒ ํ์ธ์
- ๋ํ์ ์ธ ์ํฌ๋ก๋๋ฅผ ํ๋กํ์ผ๋ง: ํ์ค์ ์ธ ๋ฐ์ดํฐ ํฌ๊ธฐ์ ํจํด ์ฌ์ฉ
- ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด๋ก ๋น๋: ์ต์ ํ์ ํจ๊ป ํฌ๊ด์ ์ธ ํ๋กํ์ผ๋ง ๋ฐ์ดํฐ ๋ฐ ์์ค ๋งคํ์ ์ํด
--debug-level=full์ฌ์ฉ - GPU ์๋ฐ์ : ์ปค๋์ ์ฌ๋ฌ ๋ฒ ์คํํ ํ ํ๋ฐ ๋ฐ๋ณต์ ํ๋กํ์ผ๋ง
- ๋์ ๋น๊ต: ํญ์ ์ฌ๋ฌ ๊ตฌํ์ ํ๋กํ์ผ๋ง
- ํซ์คํ์ ์ง์ค: ๊ฐ์ฅ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์ปค๋์ ์ต์ ํ
์ด๋ ๊ฒ ํ์ง ๋ง์ธ์
- ๋๋ฒ๊ทธ ์ ๋ณด ์์ด ํ๋กํ์ผ๋งํ์ง ๋ง ๊ฒ: ์ฑ๋ฅ์ ์์ค ์ฝ๋์ ๋งคํํ ์ ์์ (
mojo build --help) - ๋จ์ผ ์คํ๋ง ํ๋กํ์ผ๋งํ์ง ๋ง ๊ฒ: GPU ์ฑ๋ฅ์ ์คํ๋ง๋ค ๋ฌ๋ผ์ง ์ ์์
- ๋ฉ๋ชจ๋ฆฌ ์ ์ก์ ๋ฌด์ํ์ง ๋ง ๊ฒ: CPU-GPU ์ ์ก์ด ํํ ์ง๋ฐฐ์
- ์ฃ๋ถ๋ฆฌ ์ต์ ํํ์ง ๋ง ๊ฒ: ๋จผ์ ํ๋กํ์ผ๋ง, ๊ทธ๋ค์ ์ต์ ํ
ํํ ํจ์ ๊ณผ ํด๊ฒฐ์ฑ
ํจ์ 1: ์ฝ๋ ์คํํธ ํจ๊ณผ
# ์๋ชป๋ ๋ฐฉ๋ฒ: ์ฒซ ๋ฒ์งธ ์คํ์ ํ๋กํ์ผ๋ง
nsys profile mojo your_program.mojo
# ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ์๋ฐ์
ํ ํ๋กํ์ผ๋ง
nsys profile --delay=5 mojo your_program.mojo # GPU ์๋ฐ์
๋๊ธฐ
ํจ์ 2: ์๋ชป๋ ๋น๋ ๊ตฌ์ฑ
# ์๋ชป๋ ๋ฐฉ๋ฒ: ์ ์ฒด ๋๋ฒ๊ทธ ๋น๋ (์ต์ ํ ๋นํ์ฑํ) ์ฆ, `--no-optimization`
mojo build -O0 your_program.mojo -o your_program
# ์๋ชป๋ ๋ฐฉ๋ฒ: ๋๋ฒ๊ทธ ์ ๋ณด ์์ (์์ค ๋งคํ ๋ถ๊ฐ)
mojo build your_program.mojo -o your_program
# ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ํ๋กํ์ผ๋ง์ ์ํ ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด ํฌํจ ์ต์ ํ ๋น๋
mojo build --debug-level=full your_program.mojo -o optimized_program
nsys profile ./optimized_program
ํจ์ 3: ๋ฉ๋ชจ๋ฆฌ ์ ์ก ๋ฌด์
# NSight Systems์์ ์ด ํจํด์ ์ฐพ์๋ณด์ธ์:
CPU -> GPU transfer: 50ms
Kernel execution: 2ms
GPU -> CPU transfer: 48ms
# ์ด: 100ms (์ปค๋์ ๊ฒจ์ฐ 2%!)
ํด๊ฒฐ์ฑ : ์ ์ก๊ณผ ์ฐ์ฐ์ ์ค์ฒฉํ๊ณ ์ ์ก ๋น๋๋ฅผ ์ค์ด๊ธฐ (Part IX์์ ๋ค๋ฃธ)
ํจ์ 4: ๋จ์ผ ์ปค๋์๋ง ์ง์ค
# ์๋ชป๋ ๋ฐฉ๋ฒ: "๋๋ฆฐ" ์ปค๋๋ง ํ๋กํ์ผ๋ง
ncu --kernel-name regex:slow_kernel program
# ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ๋จผ์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ ํ๋กํ์ผ๋ง
nsys profile mojo program.mojo # ์ค์ ๋ณ๋ชฉ ์ฐพ๊ธฐ
๋ชจ๋ฒ ์ฌ๋ก์ ๊ณ ๊ธ ์ต์
๊ณ ๊ธ NSight Systems ํ๋กํ์ผ๋ง
ํฌ๊ด์ ์ธ ์์คํ
์ ์ฒด ๋ถ์์ ์ํด ๋ค์ ๊ณ ๊ธ nsys ํ๋๊ทธ๋ฅผ ์ฌ์ฉํฉ๋๋ค:
# ํ๋ก๋์
๊ธ ํ๋กํ์ผ๋ง ๋ช
๋ น
nsys profile \
--gpu-metrics-devices=all \
--trace=cuda,osrt,nvtx \
--trace-fork-before-exec=true \
--cuda-memory-usage=true \
--cuda-um-cpu-page-faults=true \
--cuda-um-gpu-page-faults=true \
--opengl-gpu-workload=false \
--delay=2 \
--duration=30 \
--sample=cpu \
--cpuctxsw=process-tree \
--output=comprehensive_profile \
--force-overwrite=true \
./your_program
ํ๋๊ทธ ์ค๋ช :
--gpu-metrics-devices=all: ๋ชจ๋ ๋๋ฐ์ด์ค์์ GPU ์งํ ์์ง--trace=cuda,osrt,nvtx: ํฌ๊ด์ API ์ถ์ --cuda-memory-usage=true: ๋ฉ๋ชจ๋ฆฌ ํ ๋น/ํด์ ์ถ์ --cuda-um-cpu/gpu-page-faults=true: Unified Memory ํ์ด์ง ํดํธ ๋ชจ๋ํฐ๋ง--delay=2: ํ๋กํ์ผ๋ง ์ 2์ด ๋๊ธฐ (์ฝ๋ ์คํํธ ํํผ)--duration=30: ์ต๋ 30์ด๊ฐ ํ๋กํ์ผ๋ง--sample=cpu: ํซ์คํ ๋ถ์์ ์ํ CPU ์ํ๋ง ํฌํจ--cpuctxsw=process-tree: CPU ์ปจํ ์คํธ ์ค์์น ์ถ์
๊ณ ๊ธ NSight Compute ํ๋กํ์ผ๋ง
ํฌ๊ด์ ์งํ๋ฅผ ํฌํจํ ์์ธ ์ปค๋ ๋ถ์:
# ๋ชจ๋ ์งํ ์ธํธ๋ก ์ ์ฒด ์ปค๋ ๋ถ์
ncu \
--set full \
--import-source=on \
--kernel-id=:::1 \
--launch-skip=0 \
--launch-count=1 \
--target-processes=all \
--replay-mode=kernel \
--cache-control=all \
--clock-control=base \
--apply-rules=yes \
--check-exit-code=yes \
--export=detailed_analysis \
--force-overwrite \
./your_program
# ํน์ ์ฑ๋ฅ ์ธก๋ฉด์ ์ง์ค
ncu \
--set=@roofline \
--section=InstructionStats \
--section=LaunchStats \
--section=Occupancy \
--section=SpeedOfLight \
--section=WarpStateStats \
--metrics=sm__cycles_elapsed.avg,dram__throughput.avg.pct_of_peak_sustained_elapsed \
--kernel-name regex:your_kernel_.* \
--export=targeted_analysis \
./your_program
์ฃผ์ NSight Compute ํ๋๊ทธ:
--set full: ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์งํ ์์ง (ํฌ๊ด์ ์ด์ง๋ง ๋๋ฆผ)--set @roofline: ๋ฃจํ๋ผ์ธ ๋ถ์์ ์ต์ ํ๋ ์ธํธ--import-source=on: ๊ฒฐ๊ณผ๋ฅผ ์์ค ์ฝ๋์ ๋งคํ--replay-mode=kernel: ์ ํํ ์ธก์ ์ ์ํด ์ปค๋ ๋ฆฌํ๋ ์ด--cache-control=all: ์ผ๊ด๋ ๊ฒฐ๊ณผ๋ฅผ ์ํ GPU ์บ์ ์ ์ด--clock-control=base: ๊ธฐ๋ณธ ์ฃผํ์๋ก ํด๋ญ ๊ณ ์ --section=SpeedOfLight: Speed of Light ๋ถ์ ํฌํจ--metrics=...: ํน์ ์งํ๋ง ์์ง--kernel-name regex:pattern: ์ ๊ท์ ํจํด์ผ๋ก ์ปค๋ ์ง์ (--kernel-regex๊ฐ ์๋)
ํ๋กํ์ผ๋ง ์ํฌํ๋ก์ฐ ๋ชจ๋ฒ ์ฌ๋ก
1. ์ ์ง์ ํ๋กํ์ผ๋ง ์ ๋ต
# Step 1: ๋น ๋ฅธ ๊ฐ์ (๋น ๋ฆ)
nsys profile --trace=cuda --duration=10 --output=quick_look ./program
# Step 2: ์์ธ ์์คํ
๋ถ์ (์ค๊ฐ)
nsys profile --trace=cuda,osrt,nvtx --cuda-memory-usage=true --output=detailed ./program
# Step 3: ์ปค๋ ์ฌ์ธต ๋ถ์ (๋๋ฆฌ์ง๋ง ํฌ๊ด์ )
ncu --set=@roofline --kernel-name regex:hotspot_kernel ./program
2. ์ ๋ขฐ์ฑ์ ์ํ ๋ค์ค ์คํ ๋ถ์
# ์ฌ๋ฌ ๋ฒ ํ๋กํ์ผ๋งํ๊ณ ๋น๊ต
for i in {1..5}; do
nsys profile --output=run_${i} ./program
nsys stats run_${i}.nsys-rep > stats_${i}.txt
done
# ๊ฒฐ๊ณผ ๋น๊ต
diff stats_1.txt stats_2.txt
3. ํ๊ฒ ์ปค๋ ํ๋กํ์ผ๋ง
# ๋จผ์ ํซ์คํ ์ปค๋ ์๋ณ
nsys profile --trace=cuda,nvtx --output=overview ./program
nsys stats overview.nsys-rep | grep -A 10 "GPU Kernel Summary"
# ๊ทธ๋ฐ ๋ค์ ํน์ ์ปค๋ ํ๋กํ์ผ๋ง
ncu --kernel-name="identified_hotspot_kernel" --set full ./program
ํ๊ฒฝ ๋ฐ ๋น๋ ๋ชจ๋ฒ ์ฌ๋ก
์ต์ ๋น๋ ๊ตฌ์ฑ
# ํ๋กํ์ผ๋ง์ฉ: ์ ์ฒด ๋๋ฒ๊ทธ ์ ๋ณด ํฌํจ ์ต์ ํ ๋น๋
mojo build --debug-level=full --optimization-level=3 program.mojo -o program_profile
# ๋น๋ ์ค์ ํ์ธ
mojo build --help | grep -E "(debug|optimization)"
ํ๋กํ์ผ๋ง ํ๊ฒฝ ์ค์
# ์ผ๊ด๋ ๊ฒฐ๊ณผ๋ฅผ ์ํด GPU ๋ถ์คํธ ๋นํ์ฑํ
sudo nvidia-smi -ac 1215,1410 # ๋ฉ๋ชจ๋ฆฌ ๋ฐ GPU ํด๋ญ ๊ณ ์
# ๊ฒฐ์ ๋ก ์ ๋์ ์ค์
export CUDA_LAUNCH_BLOCKING=1 # ์ ํํ ํ์ด๋ฐ์ ์ํ ๋๊ธฐ์ ์คํ
# ํ๋กํ์ผ๋ง์ ์ํ ๋๋ผ์ด๋ฒ ์ ํ ์ํ
echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid
echo 'options nvidia "NVreg_RestrictProfilingToAdminUsers=0"' | sudo tee -a /etc/modprobe.d/nvidia-kernel-common.conf
๋ฉ๋ชจ๋ฆฌ ๋ฐ ์ฑ๋ฅ ๊ฒฉ๋ฆฌ
# ํ๋กํ์ผ๋ง ์ GPU ๋ฉ๋ชจ๋ฆฌ ์ด๊ธฐํ
nvidia-smi --gpu-reset
# ๋ค๋ฅธ GPU ํ๋ก์ธ์ค ๋นํ์ฑํ
sudo fuser -v /dev/nvidia* # GPU ์ฌ์ฉ ์ค์ธ ํ๋ก์ธ์ค ํ์ธ
sudo pkill -f cuda # ํ์์ CUDA ํ๋ก์ธ์ค ์ข
๋ฃ
# ๋์ ์ฐ์ ์์๋ก ์คํ
sudo nice -n -20 nsys profile ./program
๋ถ์ ๋ฐ ๋ณด๊ณ ๋ชจ๋ฒ ์ฌ๋ก
์ข ํฉ ๋ณด๊ณ ์ ์์ฑ
# ์ฌ๋ฌ ๋ณด๊ณ ์ ํ์ ์์ฑ
nsys stats --report=cuda_api_sum,cuda_gpu_kern_sum,cuda_gpu_mem_time_sum --format=csv --output=. profile.nsys-rep
# ์ธ๋ถ ๋ถ์์ ์ํด ๋ด๋ณด๋ด๊ธฐ
nsys export --type=sqlite profile.nsys-rep
nsys export --type=json profile.nsys-rep
# ๋น๊ต ๋ณด๊ณ ์ ์์ฑ
nsys stats --report=cuda_gpu_kern_sum baseline.nsys-rep > baseline_kernels.txt
nsys stats --report=cuda_gpu_kern_sum optimized.nsys-rep > optimized_kernels.txt
diff -u baseline_kernels.txt optimized_kernels.txt
์ฑ๋ฅ ํ๊ท ํ ์คํธ
#!/bin/bash
# CI/CD์ฉ ์๋ํ ํ๋กํ์ผ๋ง ์คํฌ๋ฆฝํธ
BASELINE_TIME=$(nsys stats baseline.nsys-rep | grep "Total Time" | awk '{print $3}')
CURRENT_TIME=$(nsys stats current.nsys-rep | grep "Total Time" | awk '{print $3}')
REGRESSION_THRESHOLD=1.10 # 10% ์ฑ๋ฅ ์ ํ ์๊ณ๊ฐ
if (( $(echo "$CURRENT_TIME > $BASELINE_TIME * $REGRESSION_THRESHOLD" | bc -l) )); then
echo "Performance regression detected: ${CURRENT_TIME}ns vs ${BASELINE_TIME}ns"
exit 1
fi
๋ค์ ๋จ๊ณ
ํ๋กํ์ผ๋ง ๊ธฐ์ด๋ฅผ ์ดํดํ์ผ๋:
- ๊ธฐ์กด ์ปค๋๋ก ์ฐ์ต: ์ด๋ฏธ ํ์๋ ํผ์ฆ๋ค์ ํ๋กํ์ผ๋งํด ๋ณด์ธ์
- ์ต์ ํ ์ค๋น: Puzzle 31์์ ์ด ํต์ฐฐ์ ์ ์ ์จ ์ต์ ํ์ ํ์ฉํฉ๋๋ค
- ๋๊ตฌ ์ตํ๊ธฐ: ๋ค์ํ NSight Systems์ NSight Compute ์ต์ ์ ์คํํด ๋ณด์ธ์
๊ธฐ์ตํ์ธ์: ํ๋กํ์ผ๋ง์ ๋จ์ํ ๋๋ฆฐ ์ฝ๋๋ฅผ ์ฐพ๋ ๊ฒ์ด ์๋๋๋ค - ํ๋ก๊ทธ๋จ์ ๋์์ ์ดํดํ๊ณ ๊ทผ๊ฑฐ ์๋ ์ต์ ํ ๊ฒฐ์ ์ ๋ด๋ฆฌ๋ ๊ฒ์ ๋๋ค.
์ถ๊ฐ ํ๋กํ์ผ๋ง ์๋ฃ: