๐Ÿง  GPU ์Šค๋ ˆ๋”ฉ vs SIMD - ์‹คํ–‰ ๊ณ„์ธต ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ

๊ฐœ์š”

์š”์†Œ๋ณ„, ํƒ€์ผ๋ง, ๋ฒกํ„ฐํ™” ํŒจํ„ด์„ ํƒ๊ตฌํ•˜๋ฉด์„œ GPU ์—ฐ์‚ฐ์„ ๊ตฌ์„ฑํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” GPU ์Šค๋ ˆ๋“œ์™€ SIMD ์—ฐ์‚ฐ ์‚ฌ์ด์˜ ๊ทผ๋ณธ์ ์ธ ๊ด€๊ณ„๋ฅผ ๋ช…ํ™•ํžˆ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‘˜์€ ์„œ๋กœ ๋‹ค๋ฅด์ง€๋งŒ ์ƒํ˜ธ ๋ณด์™„์ ์ธ ๋ณ‘๋ ฌ์„ฑ ์ˆ˜์ค€์œผ๋กœ, ์ตœ์ ์˜ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ํ•จ๊ป˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํ†ต์ฐฐ: GPU ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ์„ฑ์˜ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ , SIMD ์—ฐ์‚ฐ์ด ๊ฐ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ ๋ฒกํ„ฐํ™”๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…

GPU ์Šค๋ ˆ๋”ฉ ๊ณ„์ธต ๊ตฌ์กฐ

GPU ์‹คํ–‰์€ ํ•˜๋“œ์›จ์–ด์˜ ๋ณต์žก์„ฑ์„ ์ถ”์ƒํ™”ํ•˜๋Š” ์ž˜ ์ •์˜๋œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

GPU Device
โ”œโ”€โ”€ Grid (์ „์ฒด ๋ฌธ์ œ)
โ”‚   โ”œโ”€โ”€ Block 1 (์Šค๋ ˆ๋“œ ๊ทธ๋ฃน, ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ)
โ”‚   โ”‚   โ”œโ”€โ”€ ์›Œํ”„ 1 (32๊ฐœ ์Šค๋ ˆ๋“œ, ๋ก์Šคํ… ์‹คํ–‰)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Thread 1 โ†’ SIMD ์—ฐ์‚ฐ
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Thread 2 โ†’ SIMD ์—ฐ์‚ฐ
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ... (์ด 32๊ฐœ ์Šค๋ ˆ๋“œ)
โ”‚   โ”‚   โ””โ”€โ”€ ์›Œํ”„ 2 (32๊ฐœ ์Šค๋ ˆ๋“œ)
โ”‚   โ””โ”€โ”€ Block 2 (๋…๋ฆฝ์ ์ธ ๊ทธ๋ฃน)

๐Ÿ’ก ์ฐธ๊ณ : ์ด Part๋Š” ํ•จ์ˆ˜ํ˜• ํŒจํ„ด์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ์žˆ์œผ๋ฉฐ, ์›Œํ”„ ๋ ˆ๋ฒจ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๊ณ ๊ธ‰ GPU ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” Part VII ์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

Mojo๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋“ค:

  • ๊ทธ๋ฆฌ๋“œ/๋ธ”๋ก ๊ตฌ์„ฑ: ๋ฌธ์ œ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ž๋™ ๊ณ„์‚ฐ
  • ์›Œํ”„ ๊ด€๋ฆฌ: ํ•˜๋“œ์›จ์–ด๊ฐ€ 32๊ฐœ ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ
  • ์Šค๋ ˆ๋“œ ์Šค์ผ€์ค„๋ง: GPU ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์‹คํ–‰์„ ์ž๋™ ๊ด€๋ฆฌ
  • ๋ฉ”๋ชจ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ: ํ•จ์ˆ˜ํ˜• ์—ฐ์‚ฐ์— ์ตœ์ ์˜ ์ ‘๊ทผ ํŒจํ„ด ๋‚ด์žฅ

GPU ์Šค๋ ˆ๋“œ ๋‚ด์˜ SIMD

๊ฐ GPU ์Šค๋ ˆ๋“œ๋Š” SIMD (Single Instruction, Multiple Data) ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์š”์†Œ๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

# ํ•˜๋‚˜์˜ GPU ์Šค๋ ˆ๋“œ ๋‚ด๋ถ€:
a_simd = a.load[simd_width](idx, 0)      # float 4๊ฐœ๋ฅผ ๋™์‹œ์— ๋กœ๋“œ
b_simd = b.load[simd_width](idx, 0)      # float 4๊ฐœ๋ฅผ ๋™์‹œ์— ๋กœ๋“œ
result = a_simd + b_simd                 # 4์Œ์„ ๋™์‹œ์— ๋ง์…ˆ
output.store[simd_width](idx, 0, result) # ๊ฒฐ๊ณผ 4๊ฐœ๋ฅผ ๋™์‹œ์— ์ €์žฅ

ํŒจํ„ด ๋น„๊ต์™€ ์Šค๋ ˆ๋“œ-์ž‘์—… ๋งคํ•‘

ํ•ต์‹ฌ ์ธ์‚ฌ์ดํŠธ: ๋ชจ๋“  ํŒจํ„ด์€ ๋™์ผํ•œ ์ด ์ž‘์—…๋Ÿ‰ - SIMD_WIDTH=4๋กœ 1024๊ฐœ ์š”์†Œ์— ๋Œ€ํ•ด 256ํšŒ์˜ SIMD ์—ฐ์‚ฐ - ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ ์ด ์ž‘์—…์ด GPU ์Šค๋ ˆ๋“œ์— ์–ด๋–ป๊ฒŒ ๋ถ„๋ฐฐ๋˜๋А๋ƒ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๊ตฌ์„ฑ ๋น„๊ต (SIZE=1024, SIMD_WIDTH=4)

ํŒจํ„ด์Šค๋ ˆ๋“œ ์ˆ˜์Šค๋ ˆ๋“œ๋‹น SIMD ์—ฐ์‚ฐ๋ฉ”๋ชจ๋ฆฌ ํŒจํ„ดํŠธ๋ ˆ์ด๋“œ์˜คํ”„
์š”์†Œ๋ณ„2561๋ถ„์‚ฐ ์ ‘๊ทผ์ตœ๋Œ€ ๋ณ‘๋ ฌ์„ฑ, ๋‚ฎ์€ ์ง€์—ญ์„ฑ
ํƒ€์ผ๋ง328์†Œํ˜• ๋ธ”๋ก๋ณ‘๋ ฌ์„ฑ + ์ง€์—ญ์„ฑ ๊ท ํ˜•
์ˆ˜๋™ ๋ฒกํ„ฐํ™”832๋Œ€ํ˜• ์ฒญํฌ๋†’์€ ๋Œ€์—ญํญ, ์ ์€ ์Šค๋ ˆ๋“œ
Mojo vectorize328์Šค๋งˆํŠธ ๋ธ”๋ก์ž๋™ ์ตœ์ ํ™”

์ƒ์„ธ ์‹คํ–‰ ํŒจํ„ด

์š”์†Œ๋ณ„ ํŒจํ„ด:

Thread 0: [0,1,2,3] โ†’ Thread 1: [4,5,6,7] โ†’ ... โ†’ Thread 255: [1020,1021,1022,1023]
256 ์Šค๋ ˆ๋“œ ร— 1 SIMD ์—ฐ์‚ฐ = ์ด 256ํšŒ SIMD ์—ฐ์‚ฐ

ํƒ€์ผ๋ง ํŒจํ„ด:

Thread 0: [0:32] (8 SIMD) โ†’ Thread 1: [32:64] (8 SIMD) โ†’ ... โ†’ Thread 31: [992:1024] (8 SIMD)
32 ์Šค๋ ˆ๋“œ ร— 8 SIMD ์—ฐ์‚ฐ = ์ด 256ํšŒ SIMD ์—ฐ์‚ฐ

์ˆ˜๋™ ๋ฒกํ„ฐํ™” ํŒจํ„ด:

Thread 0: [0:128] (32 SIMD) โ†’ Thread 1: [128:256] (32 SIMD) โ†’ ... โ†’ Thread 7: [896:1024] (32 SIMD)
8 ์Šค๋ ˆ๋“œ ร— 32 SIMD ์—ฐ์‚ฐ = ์ด 256ํšŒ SIMD ์—ฐ์‚ฐ

Mojo vectorize ํŒจํ„ด:

Thread 0: [0:32] ์ž๋™ ๋ฒกํ„ฐํ™” โ†’ Thread 1: [32:64] ์ž๋™ ๋ฒกํ„ฐํ™” โ†’ ... โ†’ Thread 31: [992:1024] ์ž๋™ ๋ฒกํ„ฐํ™”
32 ์Šค๋ ˆ๋“œ ร— 8 SIMD ์—ฐ์‚ฐ = ์ด 256ํšŒ SIMD ์—ฐ์‚ฐ

์„ฑ๋Šฅ ํŠน์„ฑ๊ณผ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„

ํ•ต์‹ฌ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ์š”์•ฝ

์ธก๋ฉด์Šค๋ ˆ๋“œ ๋งŽ์Œ (์š”์†Œ๋ณ„)์Šค๋ ˆ๋“œ ์ค‘๊ฐ„ (ํƒ€์ผ๋ง/vectorize)์Šค๋ ˆ๋“œ ์ ์Œ (์ˆ˜๋™)
๋ณ‘๋ ฌ์„ฑ์ตœ๋Œ€ ์ง€์—ฐ ์‹œ๊ฐ„ ์€๋‹‰๊ท ํ˜• ์žกํžŒ ์ ‘๊ทผ์ตœ์†Œํ•œ์˜ ๋ณ‘๋ ฌ์„ฑ
์บ์‹œ ์ง€์—ญ์„ฑ์Šค๋ ˆ๋“œ ๊ฐ„ ๋‚ฎ์Œํƒ€์ผ ๋‚ด์—์„œ ์–‘ํ˜ธ์ˆœ์ฐจ ์ ‘๊ทผ์œผ๋กœ ์šฐ์ˆ˜
๋ฉ”๋ชจ๋ฆฌ ๋Œ€์—ญํญ์–‘ํ˜ธํ•œ ๋ณ‘ํ•ฉ์–‘ํ˜ธ + ์บ์‹œ ์žฌ์‚ฌ์šฉ์ด๋ก ์  ์ตœ๋Œ“๊ฐ’
๋ณต์žก๋„๊ฐ€์žฅ ๋‹จ์ˆœ๋ณดํ†ต๊ฐ€์žฅ ๋ณต์žก

๊ฐ ํŒจํ„ด์˜ ์„ ํƒ ๊ธฐ์ค€

์š”์†Œ๋ณ„ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ๋•Œ:

  • ์š”์†Œ๋‹น ์—ฐ์‚ฐ๋Ÿ‰์ด ์ ์€ ๋‹จ์ˆœํ•œ ์—ฐ์‚ฐ
  • ์ง€์—ฐ ์‹œ๊ฐ„ ์€๋‹‰์„ ์œ„ํ•ด ์ตœ๋Œ€ ๋ณ‘๋ ฌ์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ๋‹ค์–‘ํ•œ ๋ฌธ์ œ ํฌ๊ธฐ์— ๋Œ€ํ•œ ํ™•์žฅ์„ฑ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ

ํƒ€์ผ๋ง/vectorize๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ:

  • ๋ฐ์ดํ„ฐ ์žฌ์‚ฌ์šฉ์˜ ์ด์ ์ด ์žˆ๋Š” ์บ์‹œ ๋ฏผ๊ฐ ์—ฐ์‚ฐ
  • ์„ฑ๋Šฅ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์˜ ๊ท ํ˜•์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ์ž๋™ ์ตœ์ ํ™”(vectorize)๊ฐ€ ์„ ํ˜ธ๋˜๋Š” ๊ฒฝ์šฐ

์ˆ˜๋™ ๋ฒกํ„ฐํ™”๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ:

  • ๋ฉ”๋ชจ๋ฆฌ ํŒจํ„ด์— ๋Œ€ํ•œ ์ „๋ฌธ๊ฐ€ ์ˆ˜์ค€์˜ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ์ตœ๋Œ€ ๋ฉ”๋ชจ๋ฆฌ ๋Œ€์—ญํญ ํ™œ์šฉ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ
  • ๊ฐœ๋ฐœ ๋ณต์žก๋„๋ฅผ ๊ฐ์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ

ํ•˜๋“œ์›จ์–ด ๊ณ ๋ ค ์‚ฌํ•ญ

ํ˜„๋Œ€ GPU ์•„ํ‚คํ…์ฒ˜์—๋Š” Mojo๊ฐ€ ์ถ”์ƒํ™”ํ•˜๋Š” ์—ฌ๋Ÿฌ ์ˆ˜์ค€์ด ์žˆ์Šต๋‹ˆ๋‹ค:

ํ•˜๋“œ์›จ์–ด ์‹ค์ œ ๊ตฌ์กฐ:

  • ์›Œํ”„: 32๊ฐœ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ก์Šคํ…์œผ๋กœ ์‹คํ–‰
  • Streaming Multiprocessor (SM): ์—ฌ๋Ÿฌ ์›Œํ”„๊ฐ€ ๋™์‹œ์— ์‹คํ–‰
  • SIMD ์œ ๋‹›: ๊ฐ SM ๋‚ด์˜ ๋ฒกํ„ฐ ์ฒ˜๋ฆฌ ์œ ๋‹›
  • ๋ฉ”๋ชจ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ: L1/L2 ์บ์‹œ, ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ, ์ „์—ญ ๋ฉ”๋ชจ๋ฆฌ

Mojo ์ถ”์ƒํ™”์˜ ์ด์ :

  • ์›Œํ”„ ์ •๋ ฌ๊ณผ ์Šค์ผ€์ค„๋ง์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ
  • ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ํŒจํ„ด์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ตœ์ ํ™”
  • SM ๊ฐ„ ๋ฆฌ์†Œ์Šค ํ• ๋‹น์„ ๊ด€๋ฆฌ
  • GPU ๋ฒค๋” ๊ฐ„ ์ด์‹ ๊ฐ€๋Šฅํ•œ ์„ฑ๋Šฅ ์ œ๊ณต

์„ฑ๋Šฅ์— ๋Œ€ํ•œ ์‚ฌ๊ณ  ๋ชจ๋ธ

GPU ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋‘ ๊ฐ€์ง€ ์ƒํ˜ธ ๋ณด์™„์ ์ธ ๋ณ‘๋ ฌ์„ฑ ์œ ํ˜•์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜์„ธ์š”:

์Šค๋ ˆ๋“œ ์ˆ˜์ค€ ๋ณ‘๋ ฌ์„ฑ:

  • ๋ณ‘๋ ฌ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณต (์‹คํ–‰ ์œ ๋‹›์˜ ์ˆ˜)
  • ๋™์‹œ ์‹คํ–‰์„ ํ†ตํ•œ ์ง€์—ฐ ์‹œ๊ฐ„ ์€๋‹‰ ๊ฐ€๋Šฅ
  • GPU ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ

SIMD ์ˆ˜์ค€ ๋ณ‘๋ ฌ์„ฑ:

  • ๊ฐ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ ๋ฒกํ„ฐํ™”๋ฅผ ์ œ๊ณต
  • ์Šค๋ ˆ๋“œ๋‹น ์‚ฐ์ˆ  ์ฒ˜๋ฆฌ๋Ÿ‰์„ ๊ทน๋Œ€ํ™”
  • ๋ฒกํ„ฐ ์ฒ˜๋ฆฌ ์œ ๋‹›์„ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉ

์ตœ์  ์„ฑ๋Šฅ ๊ณต์‹:

์„ฑ๋Šฅ = (์ง€์—ฐ ์‹œ๊ฐ„ ์€๋‹‰์„ ์œ„ํ•œ ์ถฉ๋ถ„ํ•œ ์Šค๋ ˆ๋“œ) ร—
       (ํšจ์œจ์ ์ธ SIMD ํ™œ์šฉ) ร—
       (์ตœ์ ์˜ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ํŒจํ„ด)

ํ™•์žฅ์„ฑ ๊ณ ๋ ค ์‚ฌํ•ญ

๋ฌธ์ œ ํฌ๊ธฐ์ตœ์  ํŒจํ„ด๊ทผ๊ฑฐ
์†Œ๊ทœ๋ชจ (< 1K)ํƒ€์ผ๋ง/vectorize๋‚ฎ์€ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ
์ค‘๊ทœ๋ชจ (1K-1M)๋ชจ๋“  ํŒจํ„ด์œ ์‚ฌํ•œ ์„ฑ๋Šฅ
๋Œ€๊ทœ๋ชจ (> 1M)๋ณดํ†ต ์š”์†Œ๋ณ„๋ณ‘๋ ฌ์„ฑ์ด ์ง€๋ฐฐ์ 

์ตœ์ ์˜ ์„ ํƒ์€ ํŠน์ • ํ•˜๋“œ์›จ์–ด, ์›Œํฌ๋กœ๋“œ ๋ณต์žก๋„, ๊ฐœ๋ฐœ ์ œ์•ฝ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„

GPU ์Šค๋ ˆ๋”ฉ vs SIMD ๊ฐœ๋…์„ ํ™•์‹คํžˆ ์ดํ•ดํ–ˆ๋‹ค๋ฉด:

๐Ÿ’ก ํ•ต์‹ฌ ์š”์•ฝ: GPU ์Šค๋ ˆ๋“œ์™€ SIMD ์—ฐ์‚ฐ์€ ์ƒํ˜ธ ๋ณด์™„์ ์ธ ๋ณ‘๋ ฌ์„ฑ ์ˆ˜์ค€์œผ๋กœ ํ•จ๊ป˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‘˜์˜ ๊ด€๊ณ„๋ฅผ ์ดํ•ดํ•˜๋ฉด ๊ตฌ์ฒด์ ์ธ ์„ฑ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ์ œ์•ฝ ์กฐ๊ฑด์— ๋งž๋Š” ์˜ฌ๋ฐ”๋ฅธ ํŒจํ„ด์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.