GPU μ±λ₯ μ΄ν΄νκΈ°: 루νλΌμΈ λͺ¨λΈ
κΈ°λ³Έ νλ ¬ κ³±μ μ ꡬννμΌλ, μ΄λ° κΆκΈμ¦μ΄ μκΈΈ μ μμ΅λλ€: μ°λ¦¬ 컀λμ μ€μ λ‘ μΌλ§λ μ λμνκ³ μμκΉ? GPUμ μ°μ° λ₯λ ₯μ μν΄ μ νλλ κ±ΈκΉ, μλλ©΄ λ€λ₯Έ 무μΈκ°κ° λ°λͺ©μ μ‘κ³ μλ κ±ΈκΉ?
루νλΌμΈ λͺ¨λΈ(μμ£Ό: 루νλΌμΈμ βμνμ βμ΄λΌλ λ»μΌλ‘, μ±λ₯μ΄ λμ μ μλ νκ³λ₯Ό μ§λΆ μ μ λΉμ ν μ΄λ¦μ λλ€)μ GPU μ΅μ νμ λμΉ¨λ°μ λλ€. 컀λμ μ±λ₯μ μ ννλ νλμ¨μ΄ λ³λͺ©μ΄ 무μμΈμ§ μλ €μ£Όκ³ , κ°μ₯ ν¨κ³Όμ μΈ μ΅μ ν λ°©ν₯μΌλ‘ μλ΄ν©λλ€. κ°μΌλ‘ κ°μ νλ λμ , 루νλΌμΈ λͺ¨λΈμ΄ μ νν μ΄λμ μ§μ€ν΄μΌ νλμ§ λ³΄μ¬μ€λλ€.
1. λͺ¨λ GPU 컀λμ λ κ°μ§ μ±λ₯ μν
λͺ¨λ GPU 컀λμ λ κ°μ§ κ·Όλ³Έμ μΈ μ μ½ μλμμ λμν©λλ€:
- μ°μ° μν(compute ceiling) β μ½μ΄κ° λΆλμμμ μ°μ°μ μΌλ§λ λΉ λ₯΄κ² μνν μ μλκ° (μ΅λ FLOPs/s)
- λ©λͺ¨λ¦¬ μν(memory ceiling) β λ©λͺ¨λ¦¬ μμ€ν μ΄ μ½μ΄μ λ°μ΄ν°λ₯Ό μΌλ§λ λΉ λ₯΄κ² 곡κΈν μ μλκ° (μ΅λ bytes/s)
μ΄λ€ μνμ΄ μ»€λμ μ μ½νλμ§ νμ νλ κ²μ΄ μ΅μ ν μ λ΅μ ν΅μ¬μ λλ€. 루νλΌμΈ λͺ¨λΈμ λ κ°μ§ ν΅μ¬ μ§νλ₯Ό κ·Έλνλ‘ νννμ¬ μ΄ κ΄κ³λ₯Ό μκ°νν©λλ€:
XμΆ: μ°μ κ°λ(Arithmetic Intensity) β λ°μ΄ν° 1λ°μ΄νΈλΉ μννλ μ°μ°λ
\[\Large I = \frac{\text{Total FLOPs}}{\text{Total Bytes from Memory}} \quad [\text{FLOP/B}]\]
YμΆ: μ€μΈ‘ μ±λ₯(Sustained Performance) β 컀λμ΄ μ€μ λ‘ λ¬μ±νλ μλ
\[\Large P_{\text{sustained}} = \frac{\text{Total FLOPs}}{\text{Elapsed Time}} \quad [\text{GFLOP/s}]\]
λ κ°μ βμν(roof)βμ΄ λ¬μ± κ°λ₯ν μ±λ₯μ μνμ μ ν©λλ€:
| μν | μμ | μλ―Έ |
|---|---|---|
| λ©λͺ¨λ¦¬ μν | \(P = B_{\text{peak}} \cdot I\) | κΈ°μΈμ΄μ§ μ§μ . λ©λͺ¨λ¦¬ λμνμ μν΄ μ±λ₯μ΄ μ νλ¨ |
| μ°μ° μν | \(P = P_{\text{peak}}\) | μνμ . μ°μ° μ²λ¦¬λμ μν΄ μ±λ₯μ΄ μ νλ¨ |
μκ³ κ°λ(critical intensity)
\[\Large I^* = \frac{P_{\text{peak}}}{B_{\text{peak}}}\]
λ 컀λμ΄ λ©λͺ¨λ¦¬ λ°μ΄λ(\(I < I^\ast\) )μμ μ°μ° λ°μ΄λ(\(I > I^\ast\) )λ‘ μ νλλ μ§μ μ λλ€.
2. νλμ¨μ΄ μμ: NVIDIA A100 μ¬μ
μ΄λ‘ μ NVIDIA A100μ ꡬ체μ μΈ μ«μλ‘ νμΈν΄ λ³΄κ² μ΅λλ€:
μ΅λ FP32 μ²λ¦¬λ \[\Large P_{\text{peak}} = 19.5 \text{ TFLOP/s} = 19{,}500 \text{ GFLOP/s}\]
μ΅λ HBM2 λμν \[\Large B_{\text{peak}} = 1{,}555 \text{ GB/s}\]
μκ³ κ°λ \[\Large I^* = \frac{19{,}500}{1{,}555} \approx 12.5 \text{ FLOP/B}\]
μΆμ²: NVIDIA A100 Tensor Core GPU Architecture
μ΄λ μ°μ κ°λκ° 12.5 FLOP/B λ―Έλ§μΈ 컀λμ λ©λͺ¨λ¦¬ λ°μ΄λ, κ·Έ μ΄μμΈ μ»€λμ μ°μ° λ°μ΄λμμ λ»ν©λλ€.
3. νλ ¬ κ³±μ ꡬνμ μκ°ν
μλ μ λλ©μ΄μ μ μ΄ νΌμ¦μ ꡬνλ€μ΄ A100μ 루νλΌμΈ λͺ¨λΈμ μ΄λ»κ² λμνλμ§ λ³΄μ¬μ€λλ€:

μ΄ μκ°νλ μ΄ νΌμ¦μμ κ±°μΉκ² λ μ΅μ ν κ³Όμ μ 보μ¬μ€λλ€:
- νλμ¨μ΄ μ μ½ β λΉ¨κ°μ λ©λͺ¨λ¦¬ μνκ³Ό νλμ μ°μ° μνμ΄ μ±λ₯ νκ³λ₯Ό μ μ
- μΆλ°μ β κΈ°λ³Έ ꡬν(μ£Όν©μ μ )μ΄ λ©λͺ¨λ¦¬ μν μμ μμΉ
- μ΅μ ν λͺ©ν β 곡μ λ©λͺ¨λ¦¬ λ²μ (μ²λ‘μ μ )μΌλ‘ μ°μ κ°λκ° κ°μ λ¨
- κΆκ·Ήμ λͺ©ν β κΈμ νμ΄νλ 컀λμ΄ μ°μ° λ°μ΄λκ° λλ μκ³ κ°λ μ§μ μ κ°λ¦¬ν΄
4. κΈ°λ³Έ ꡬν λΆμ
μ΄μ μΉμ μ κΈ°λ³Έ 컀λμ΄ μ μ΄λ° μ±λ₯μ 보μ΄λμ§ μ΄ν΄λ³΄κ² μ΅λλ€. \(2 \times 2\) νλ ¬ κ³±μ μ κ²½μ°:
μΆλ ₯ μμλΉ μ°μ°λ: \(\text{SIZE} + (\text{SIZE}-1) = 3 \text{ FLOPs }\)
κ° μμμλ \(\text{SIZE}\) νμ κ³±μ κ³Ό \(\text{SIZE} - 1\) νμ λ§μ μ΄ νμν©λλ€: \[C_{00} = A_{00} \cdot B_{00} + A_{01} \cdot B_{10}\] \(\text{SIZE} = 2\) μΌ λ κ³±μ 2ν + λ§μ 1ν = 3 FLOPs
μΆλ ₯ μμλΉ λ©λͺ¨λ¦¬ μ κ·Ό:
- νλ ¬ Aμ ν: \(2 \times 4 = 8\) bytes (FP32)
- νλ ¬ Bμ μ΄: \(2 \times 4 = 8\) bytes (FP32)
- ν©κ³: μΆλ ₯ μμλΉ \(16\) bytes
μ°μ κ°λ: \[\Large I_{\text{naive}} = \frac{3 \text{ FLOPs}}{16 \text{ bytes}} = 0.1875 \text{ FLOP/B}\]
μ΄ μ°μ κ°λλ A100μ μκ³ κ°λμ νμ°Έ λͺ» λ―ΈμΉλ―λ‘, κΈ°λ³Έ 컀λμ μ¬κ°ν λ©λͺ¨λ¦¬ λ°μ΄λ μνμ λλ€.
\[\Large I_{\text{naive}} = 0.1875 \ll I^* = 12.5\]
μμ μ±λ₯: \[\Large P \approx B_{\text{peak}} \times I_{\text{naive}} = 1{,}555 \times 0.1875 \approx 292 \text{ GFLOP/s}\]
μ΄λ GPU μ°μ° μ μ¬λ ₯μ \(\frac{292}{19{,}500} \approx 1.5\%\) μ λΆκ³Όν©λλ€! μκ°νμμ λ Έλμ μ μ΄ λ©λͺ¨λ¦¬ μν μμ λμΈ κ²μ΄ μ΄λ₯Ό μ 보μ¬μ€λλ€ β μ°μ° μνμλ νμ°Έ λ―ΈμΉμ§ λͺ»νλ μμ€μ λλ€.
5. λ€μ λ¨κ³: 곡μ λ©λͺ¨λ¦¬ μ΅μ ν
루νλΌμΈ λͺ¨λΈμ΄ μλ €μ£Όλ μ΅μ ν μ λ΅μ λͺ νν©λλ€: μ€λ³΅ λ©λͺ¨λ¦¬ μ κ·Όμ μ€μ¬ μ°μ κ°λλ₯Ό λμ΄λ κ²μ λλ€. 곡μ λ©λͺ¨λ¦¬ μ κ·Όλ²μ΄ λ°λ‘ μ΄λ₯Ό λ¬μ±ν©λλ€:
곡μ λ©λͺ¨λ¦¬μ μ΄μ :
- νλ ₯μ λ‘λ©: μ€λ λλ€μ΄ ν¨κ» νλ ¬ λΈλ‘μ λΉ λ₯Έ 곡μ λ©λͺ¨λ¦¬μ λ‘λ
- λ°μ΄ν° μ¬μ¬μ©: λ‘λν μμ νλλ₯Ό μ¬λ¬ μ°μ°μ νμ©
- μ μ λ©λͺ¨λ¦¬ νΈλν½ κ°μ: λλ¦° μ μ λ©λͺ¨λ¦¬μ λν μ κ·Ό νμ κ°μ
μ°μ κ°λ κ°μ μμμΉ: \[\Large I_{\text{shared}} = \frac{12 \text{ FLOPs}}{32 \text{ bytes}} = 0.375 \text{ FLOP/B}\]
μμ \(2 \times 2\) κ·λͺ¨μμλ μ¬μ ν λ©λͺ¨λ¦¬ λ°μ΄λμ΄μ§λ§, μ΄ 2λ°°μ μ°μ κ°λ ν₯μμ 곡μ λ©λͺ¨λ¦¬ νμΌμ ν¨μ¬ λ λ§μ΄ μ¬μ¬μ©ν μ μλ ν° νλ ¬μμ κ·Ήμ μΈ ν¨κ³Όλ₯Ό λ°νν©λλ€.
6. 루νλΌμΈμ΄ μλ €μ£Όλ μ΅μ ν μ λ΅
루νλΌμΈ λͺ¨λΈμ νμ¬ μ±λ₯μ μ§λ¨ν λΏ μλλΌ, μ΅μ ν λ°©ν₯κΉμ§ μλ €μ€λλ€. μ΄ν νΌμ¦μμ μ΄ν΄λ³Ό ν΅μ¬ κΈ°λ²μ λ€μκ³Ό κ°μ΅λλ€:
| κΈ°λ² | 루νλΌμΈ ν¨κ³Ό | ꡬν λ°©λ² |
|---|---|---|
| 곡μ λ©λͺ¨λ¦¬ νμΌλ§ | λ°μ΄ν° μ¬μ¬μ©μΌλ‘ μ°μ κ°λ β | νλ ₯μ λ‘λ©, λΈλ‘ λ¨μ μ°μ° |
| λ μ§μ€ν° λΈλ‘νΉ | λ μ§μ€ν° λμ μΌλ‘ λ©λͺ¨λ¦¬ νΈλν½ κ°μ | λ μ§μ€ν° λ³μμ 루ν μ κ° |
| 컀λ ν¨μ | μ°μ° κ²°ν©μΌλ‘ λ°μ΄νΈλΉ FLOPs μ¦κ° | λ¨μΌ 컀λμμ μ¬λ¬ μ°μ° λ¨κ³ μ²λ¦¬ |
| λ©λͺ¨λ¦¬ λ³ν©(coalescing) | μ€ν¨ λμν νμ© κ·Ήλν | ꡬ쑰νλ μ κ·Ό ν¨ν΄, μ μ ν μ€λ λ κ΅¬μ± |
| λΉλκΈ° λ©λͺ¨λ¦¬ λ³΅μ¬ | μ μ© λ³΅μ¬ μμ§μΌλ‘ μ°μ°-λ©λͺ¨λ¦¬ μ€μ²© | copy_dram_to_sram_asyncμ μ°μ° μ€μ²© |
| νΌν© μ λ°λ | μμ λ°μ΄ν° νμ μΌλ‘ λ©λͺ¨λ¦¬ λΆν κ°μ | FP16/BF16 μ λ ₯ + FP32 λμ |
κ° κΈ°λ²μ 컀λμ 루νλΌμΈ μμμ μ΄λμν΅λλ€ β λ©λͺ¨λ¦¬ μνμ λ°λΌ μλ‘(λμν νμ© κ°μ ), λλ μ€λ₯Έμͺ½ μ°μ° μνμ ν₯ν΄(μ°μ κ°λ ν₯μ).
λΉλκΈ° μ°μ°μ λν μ°Έκ³ : νμ€ GPU λ©λͺ¨λ¦¬ λ‘λ(ld.global)λ μ΄λ―Έ λΉλκΈ°μ
λλ€ β μνλ λ‘λν λ°μ΄ν°κ° μ€μ λ‘ νμν΄μ§ λκΉμ§ κ³μ μ€νλ©λλ€. cp.async(CUDA)λ copy_dram_to_sram_async(Mojo) κ°μ μ μ© λΉλκΈ° λ³΅μ¬ λͺ
λ Ήμ μ¬κΈ°μ ν κ±Έμ λ λμκ°, μ μ© λ³΅μ¬ μμ§μ μ¬μ©νκ³ λ μ§μ€ν°λ₯Ό μ°ννμ¬ μμ νμ©μ λμ
λλ€. λ¨μν λκΈ° μ°μ°μ λΉλκΈ°λ‘ λ°κΎΈλ κ²κ³Όλ λ€λ¦
λλ€.
7. λ¨μν 루νλΌμΈμ λμ΄μ
λ€λ¨κ³ λ©λͺ¨λ¦¬: κ³ κΈ λ£¨νλΌμΈμ L2 μΊμ, 곡μ λ©λͺ¨λ¦¬, λ μ§μ€ν° λμνμ λν΄ λ³λμ μνμ ν¬ν¨νμ¬ μ΄λ€ λ©λͺ¨λ¦¬ κ³μΈ΅μ΄ μ±λ₯μ μ μ½νλμ§ μλ³ν©λλ€.
ν΅μ 루νλΌμΈ: λ©ν° GPU μ ν리μΌμ΄μ μμλ λ©λͺ¨λ¦¬ λμν λμ μΈν°μ»€λ₯νΈ λμν(NVLink, InfiniBand)μ μ¬μ©νμ¬ μ€μΌμΌλ§ ν¨μ¨μ λΆμν©λλ€.
μ μ© μ λ: μ΅μ GPUλ κ³ μ ν μ±λ₯ νΉμ±μ κ°μ§ ν μ μ½μ΄λ₯Ό ν¬ν¨νλ©°, λ³λμ 루νλΌμΈ λΆμμ΄ νμν©λλ€.
8. μ€μ μμ 루νλΌμΈ νμ©νκΈ°
- 컀λ νλ‘νμΌλ§: Nsight Compute κ°μ λκ΅¬λ‘ μ€μ FLOPsμ λ©λͺ¨λ¦¬ νΈλν½ μΈ‘μ
- λ°μ΄ν° ν¬μΈνΈ νμ: μ°μ κ°λμ μ€μΈ‘ μ±λ₯ κ³μ°
- λ³λͺ© μλ³: λ©λͺ¨λ¦¬ λ°μ΄λ 컀λμ λ©λͺ¨λ¦¬ μν μμ, μ°μ° λ°μ΄λ 컀λμ μ°μ° μνμ κ·Όμ
- μ΅μ ν μ ν: λ©λͺ¨λ¦¬ λ°μ΄λ 컀λμλ λμν κ°μ μ, μ°μ° λ°μ΄λ 컀λμλ μκ³ λ¦¬μ¦ λ³κ²½μ μ§μ€
- μΈ‘μ κ³Ό λ°λ³΅: μ΅μ νκ° μ»€λμ κΈ°λν λ°©ν₯μΌλ‘ μ΄λμν€λμ§ κ²μ¦
곡μ λ©λͺ¨λ¦¬ νΌμ¦κ³Όμ μ°κ²°
λ€μ μΉμ μμλ 컀λμ 루νλΌμΈ μλ‘ λμ΄μ¬λ¦¬κΈ° μμνλ 곡μ λ©λͺ¨λ¦¬ μ΅μ νλ₯Ό ꡬνν©λλ€. μκ°νμμ λ³Ό μ μλ―μ΄, μ£Όν©μ μ (κΈ°λ³Έ)μμ μ²λ‘μ μ (곡μ λ©λͺ¨λ¦¬)μΌλ‘ μ΄λνκ² λ©λλ€ β λ°μ΄ν° μ¬μ¬μ© κ°μ μ ν΅ν νμ€ν μ±λ₯ ν₯μμ λλ€.
\(2 \times 2\) μμ μμλ μ°μ° μνμ λλ¬νμ§ λͺ»νμ§λ§, 곡μ λ©λͺ¨λ¦¬κ° μ±λ₯μ κ²°μ μ μΈ μν μ νλ ν° νλ ¬μμ λμΌν μλ¦¬κ° μ΄λ»κ² νμ₯λλμ§ νμΈν μ μμ΅λλ€. 루νλΌμΈ λͺ¨λΈμ 곡μ λ©λͺ¨λ¦¬κ° μ λμμ΄ λκ³ μΌλ§λ κ°μ μ κΈ°λν μ μλμ§ μ΄ν΄νκΈ° μν μ΄λ‘ μ ν λλ₯Ό μ 곡ν©λλ€.
루νλΌμΈ λͺ¨λΈμ μ΄ν΄νλ©΄ GPU μ΅μ νκ° μΆμΈ‘μμ 체κ³μ μΈ μμ§λμ΄λ§μΌλ‘ λ°λλλ€. μ΄ μ± μ λͺ¨λ μ΅μ ν κΈ°λ²μ μ΄ λ¨μνμ§λ§ κ°λ ₯ν μ±λ₯ λͺ¨λΈμ λν ν¨κ³Όλ‘ μ΄ν΄ν μ μμ΅λλ€.