block.broadcast()์ ๋ฒกํฐ ์ ๊ทํ
block.sum๊ณผ block.broadcast ์ฐ์ฐ์ ๊ฒฐํฉํ์ฌ ๋ฒกํฐ ํ๊ท ์ ๊ทํ๋ฅผ ๊ตฌํํ๊ณ , ๋ธ๋ก ๋ ๋ฒจ ํต์ ์ํฌํ๋ก์ฐ์ ์ ์ฒด ๋ชจ์ต์ ๋ณด์ฌ์ค๋๋ค. ๊ฐ ์ค๋ ๋๊ฐ ํ๊ท ๊ณ์ฐ์ ๊ธฐ์ฌํ ๋ค์, ๋ธ๋ก๋์บ์คํธ๋ ํ๊ท ์ ๋ฐ์ ์์ ์ ์์๋ฅผ ์ ๊ทํํ์ฌ, ๋ธ๋ก ์ฐ์ฐ์ด ์ค์ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ํด๊ฒฐํ๊ธฐ ์ํด ์ด๋ป๊ฒ ํจ๊ป ๋์ํ๋์ง ๋ณด์ฌ์ค๋๋ค.
ํต์ฌ ํต์ฐฐ: block.broadcast() ์ฐ์ฐ์ ํ๋โ์ ์ฒด ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํ์ฌ, ๊ธฐ๋ณธ ๋ธ๋ก ํต์ ํจํด์ ์์ฑํฉ๋๋ค: ๋ฆฌ๋์ (์ ์ฒดโํ๋), ์ค์บ(์ ์ฒดโ๊ฐ๊ฐ), ๋ธ๋ก๋์บ์คํธ(ํ๋โ์ ์ฒด).
ํต์ฌ ๊ฐ๋
์ด ํผ์ฆ์์ ๋ฐฐ์ธ ๋ด์ฉ:
block.broadcast()๋ฅผ ํ์ฉํ ๋ธ๋ก ๋ ๋ฒจ ๋ธ๋ก๋์บ์คํธ- ํ๋โ์ ์ฒด ํต์ ํจํด
- ์์ค ์ค๋ ๋ ์ง์ ๊ณผ ํ๋ผ๋ฏธํฐ ์ ์ด
- ์ฌ๋ฌ ์ฐ์ฐ์ ๊ฒฐํฉํ๋ ์์ ํ ๋ธ๋ก ์ฐ์ฐ ์ํฌํ๋ก์ฐ
- ์กฐ์จ๋ ๋ธ๋ก ๊ธฐ๋ณธ ์์๋ฅผ ์ฌ์ฉํ ์ค์ ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ
์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฒกํฐ ํ๊ท ์ ๊ทํ๋ฅผ ๋ณด์ฌ์ค๋๋ค: \[\Large \text{output}[i] = \frac{\text{input}[i]}{\frac{1}{N}\sum_{j=0}^{N-1} \text{input}[j]}\]
๊ฐ ์ค๋ ๋๊ฐ ํ๊ท ๊ณ์ฐ์ ๊ธฐ์ฌํ ๋ค์, ๋ธ๋ก๋์บ์คํธ๋ ํ๊ท ์ ๋ฐ์ ์์ ์ ์์๋ฅผ ์ ๊ทํํฉ๋๋ค.
๊ตฌ์ฑ
- ๋ฒกํฐ ํฌ๊ธฐ:
SIZE = 128์์ - ๋ฐ์ดํฐ ํ์
:
DType.float32 - ๋ธ๋ก ๊ตฌ์ฑ:
(128, 1)๋ธ๋ก๋น ์ค๋ ๋ ์ (TPB = 128) - ๊ทธ๋ฆฌ๋ ๊ตฌ์ฑ:
(1, 1)๊ทธ๋ฆฌ๋๋น ๋ธ๋ก ์ - ๋ ์ด์์:
Layout.row_major(SIZE)(์ ๋ ฅ๊ณผ ์ถ๋ ฅ ๋ชจ๋ 1D row-major) - ํ ์คํธ ๋ฐ์ดํฐ: 1-8 ๋ฐ๋ณต ๊ฐ, ํ๊ท = 4.5
- ์์ ์ถ๋ ฅ: ํ๊ท ์ด 1.0์ธ ์ ๊ทํ๋ ๋ฒกํฐ
๋์ ๊ณผ์ : ๋ธ๋ก ์ ์ฒด ๊ณ์ฐ๊ณผ ๋ถ๋ฐฐ์ ์กฐ์จ
๊ธฐ์กด์ ํ๊ท ์ ๊ทํ ๋ฐฉ์์ ๋ณต์กํ ์กฐ์จ์ด ํ์ํฉ๋๋ค:
# ์์ฐจ์ ๋ฐฉ์ - ๋ณ๋ ฌ์ฑ์ ํ์ฉํ์ง ๋ชปํจ
total = sum(input_array)
mean = total / len(input_array)
output_array = [x / mean for x in input_array]
๋จ์ํ GPU ๋ณ๋ ฌํ์ ๋ฌธ์ ์ :
- ๋ค์ค ์ปค๋ ์คํ: ํ๊ท ๊ณ์ฐ๊ณผ ์ ๊ทํ์ ๊ฐ๊ฐ ๋ณ๋์ ํจ์ค๊ฐ ํ์
- ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์๋ณต: ํ๊ท ์ ์ ์ญ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ค๊ฐ ๋์ค์ ๋ค์ ์ฝ๊ธฐ
- ๋๊ธฐํ ๋ณต์ก์ฑ: ๊ณ์ฐ ๋จ๊ณ ๊ฐ์ ๋ฐฐ๋ฆฌ์ด๊ฐ ํ์
- ์ค๋ ๋ ๋ถ๊ธฐ: ์๋ก ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์๋ก ๋ค๋ฅธ ์์ ์ ์ํ
๊ธฐ์กด GPU ํ์ด์ ๋ณต์ก์ฑ:
# 1๋จ๊ณ: ํฉ๊ณ๋ฅผ ๊ตฌํ๊ธฐ ์ํ ๋ฆฌ๋์
(๋ณต์กํ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ + ๋ฐฐ๋ฆฌ์ด)
shared_sum[local_i] = my_value
barrier()
# ์ฌ๋ฌ barrier() ํธ์ถ์ด ํ์ํ ์๋ ํธ๋ฆฌ ๋ฆฌ๋์
...
# 2๋จ๊ณ: ์ค๋ ๋ 0์ด ํ๊ท ์ ๊ณ์ฐ
if local_i == 0:
mean = shared_sum[0] / size
shared_mean[0] = mean
barrier()
# 3๋จ๊ณ: ๋ชจ๋ ์ค๋ ๋๊ฐ ํ๊ท ์ ์ฝ๊ณ ์ ๊ทํ
mean = shared_mean[0] # ๋ชจ๋๊ฐ ๊ฐ์ ๊ฐ์ ์ฝ์
output[global_i] = my_value / mean
๊ณ ๊ธ ๋ฐฉ์: block.sum() + block.broadcast() ์กฐ์จ
๋ค๋จ๊ณ ์กฐ์จ์ ๊ฐ๊ฒฐํ ๋ธ๋ก ์ฐ์ฐ ์ํฌํ๋ก์ฐ๋ก ๋ณํํฉ๋๋ค:
์์ฑํ ์ฝ๋
์์ ํ ๋ธ๋ก ์ฐ์ฐ ์ํฌํ๋ก์ฐ
๋ธ๋ก ์ฐ์ฐ ๋๊ตฌ ๋ชจ์ ์ ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ ๊ธ ๋ฒกํฐ ํ๊ท ์ ๊ทํ๋ฅผ ๊ตฌํํฉ๋๋ค:
comptime vector_layout = Layout.row_major(SIZE)
fn block_normalize_vector[
in_layout: Layout, out_layout: Layout, tpb: Int
](
input_data: LayoutTensor[dtype, in_layout, ImmutAnyOrigin],
output_data: LayoutTensor[dtype, out_layout, MutAnyOrigin],
size: Int,
):
"""Vector mean normalization using block.sum() + block.broadcast() combination.
This demonstrates the complete block operations workflow:
1. Use block.sum() to compute sum of all elements (all โ one)
2. Thread 0 computes mean = sum / size
3. Use block.broadcast() to share mean to all threads (one โ all)
4. Each thread normalizes: output[i] = input[i] / mean
"""
global_i = Int(block_dim.x * block_idx.x + thread_idx.x)
local_i = thread_idx.x
# Step 1: Each thread loads its element
# FILL IN (roughly 3 lines)
# Step 2: Use block.sum() to compute total sum (familiar from earlier!)
# FILL IN (1 line)
# Step 3: Thread 0 computes mean value
# FILL IN (roughly 4 lines)
# Step 4: block.broadcast() shares mean to ALL threads!
# This completes the block operations trilogy demonstration
# FILL IN (1 line)
# Step 5: Each thread normalizes by the mean
# FILL IN (roughly 3 lines)
์ ์ฒด ํ์ผ ๋ณด๊ธฐ: problems/p27/p27.mojo
ํ
1. ์์ ํ ์ํฌํ๋ก์ฐ ๊ตฌ์กฐ (๋ชจ๋ ์ด์ ์ฐ์ฐ์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ)
์๊ณ ๋ฆฌ์ฆ์ ์๋ฒฝํ ๋ธ๋ก ์ฐ์ฐ ํจํด์ ๋ฐ๋ฆ ๋๋ค:
- ๊ฐ ์ค๋ ๋๊ฐ ์์ ์ ์์๋ฅผ ๋ก๋ (๋ชจ๋ ์ด์ ํผ์ฆ์์ ์ต์ํ ํจํด)
block.sum()์ผ๋ก ํฉ๊ณ๋ฅผ ๊ณ์ฐ (์ด ํผ์ฆ์ ์๋ถ๋ถ์์ ๋ฐฐ์ด ๋ด์ฉ)- ์ค๋ ๋ 0์ด ํฉ๊ณ๋ก๋ถํฐ ํ๊ท ์ ๊ณ์ฐ
block.broadcast()๋ก ํ๊ท ์ ๋ชจ๋ ์ค๋ ๋์ ๊ณต์ (์๋ก์ด ๋ด์ฉ!)- ๊ฐ ์ค๋ ๋๊ฐ ๋ธ๋ก๋์บ์คํธ๋ ํ๊ท ์ผ๋ก ์ ๊ทํ
2. ๋ฐ์ดํฐ ๋ก๋ฉ๊ณผ ํฉ๊ณ ๊ณ์ฐ (์ต์ํ ํจํด)
๊ธฐ์กด LayoutTensor ํจํด์ผ๋ก ์์๋ฅผ ๋ก๋ํฉ๋๋ค:
var my_value: Scalar[dtype] = 0.0
if global_i < size:
my_value = input_data[global_i][0] # SIMD ์ถ์ถ
๊ทธ๋ฐ ๋ค์ ์์ ๋ฐฐ์ด ๋ด์ ๊ณผ ๋์ผํ๊ฒ block.sum()์ ์ฌ์ฉํฉ๋๋ค:
total_sum = block.sum[block_size=tpb, broadcast=False](...)
3. ํ๊ท ๊ณ์ฐ (์ค๋ ๋ 0๋ง)
์ค๋ ๋ 0๋ง ํ๊ท ์ ๊ณ์ฐํด์ผ ํฉ๋๋ค:
var mean_value: Scalar[dtype] = 1.0 # ์์ ํ ๊ธฐ๋ณธ๊ฐ
if local_i == 0:
# total_sum๊ณผ size๋ก ํ๊ท ๊ณ์ฐ
์ ์ค๋ ๋ 0์ธ๊ฐ? block.sum() ํจํด์์ ์ค๋ ๋ 0์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ๊ฒ๊ณผ ์ผ๊ด์ฑ์ ์ ์งํฉ๋๋ค.
4. block.broadcast() API ๊ฐ๋
ํจ์ ์๊ทธ๋์ฒ๋ฅผ ์ดํด๋ณด์ธ์ - ๋ค์์ด ํ์ํฉ๋๋ค:
- ํ
ํ๋ฆฟ ํ๋ผ๋ฏธํฐ:
dtype,width,block_size - ๋ฐํ์ ํ๋ผ๋ฏธํฐ:
val(๋ธ๋ก๋์บ์คํธํ SIMD ๊ฐ),src_thread(๊ธฐ๋ณธ๊ฐ=0)
ํธ์ถ ํจํด์ ๊ธฐ์กด ํ ํ๋ฆฟ ์คํ์ผ์ ๋ฐ๋ฆ ๋๋ค:
result = block.broadcast[
dtype = DType.float32,
width = 1,
block_size = tpb
](val=SIMD[DType.float32, 1](value_to_broadcast), src_thread=UInt(0))
5. ๋ธ๋ก๋์บ์คํธ ํจํด ์ดํดํ๊ธฐ
ํต์ฌ ํต์ฐฐ: block.broadcast()๋ ํ๋์ ์ค๋ ๋์์ ๊ฐ์ ๊ฐ์ ธ์ ๋ชจ๋ ์ค๋ ๋์ ์ ๋ฌํฉ๋๋ค:
- ์ค๋ ๋ 0์ด ๊ณ์ฐ๋ ํ๊ท ๊ฐ์ ๊ฐ์ง๊ณ ์์
- ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ํ๊ท ๊ฐ์ด ํ์
block.broadcast()๊ฐ ์ค๋ ๋ 0์ ๊ฐ์ ๋ชจ๋์๊ฒ ๋ณต์ฌ
์ด๊ฒ์ block.sum()(์ ์ฒดโํ๋)์ ๋ฐ๋์ด๋ฉฐ, block.prefix_sum()(์ ์ฒดโ๊ฐ๊ฐ ์์น)๊ณผ๋ ๋ค๋ฆ
๋๋ค.
6. ์ต์ข ์ ๊ทํ ๋จ๊ณ
๋ชจ๋ ์ค๋ ๋๊ฐ ๋ธ๋ก๋์บ์คํธ๋ ํ๊ท ์ ๋ฐ์ผ๋ฉด, ์์ ์ ์์๋ฅผ ์ ๊ทํํฉ๋๋ค:
if global_i < size:
normalized_value = my_value / broadcasted_mean[0] # SIMD ์ถ์ถ
output_data[global_i] = normalized_value
SIMD ์ถ์ถ: block.broadcast()๊ฐ SIMD๋ฅผ ๋ฐํํ๋ฏ๋ก [0]์ผ๋ก ์ค์นผ๋ผ๋ฅผ ์ถ์ถํด์ผ ํฉ๋๋ค.
7. ์ด์ ํผ์ฆ์์์ ํจํด ์ธ์
- ์ค๋ ๋ ์ธ๋ฑ์ฑ: ํญ์ ๋์ผํ
global_i,local_iํจํด - ๊ฒฝ๊ณ ๊ฒ์ฌ: ๋์ผํ
if global_i < size๊ฒ์ฆ - SIMD ์ฒ๋ฆฌ: ๋์ผํ
[0]์ถ์ถ ํจํด - ๋ธ๋ก ์ฐ์ฐ:
block.sum()๊ณผ ๋์ผํ ํ ํ๋ฆฟ ํ๋ผ๋ฏธํฐ ์คํ์ผ
๊ฐ ๋ธ๋ก ์ฐ์ฐ์ด ์ผ๊ด๋ ํจํด์ ๋ฐ๋ฅด๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค!
block.broadcast() ๋ฐฉ์ ํ ์คํธ:
pixi run p27 --normalize
pixi run -e amd p27 --normalize
pixi run -e apple p27 --normalize
uv run poe p27 --normalize
ํ์์ ๋์ ์์ ์ถ๋ ฅ:
SIZE: 128
TPB: 128
Input sample: 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 ...
Sum value: 576.0
Mean value: 4.5
Mean Normalization Results:
Normalized sample: 0.22222222 0.44444445 0.6666667 0.8888889 1.1111112 1.3333334 1.5555556 1.7777778 ...
Output sum: 128.0
Output mean: 1.0
โ
Success: Output mean is 1.0 (should be close to 1.0)
์๋ฃจ์
fn block_normalize_vector[
in_layout: Layout, out_layout: Layout, tpb: Int
](
input_data: LayoutTensor[dtype, in_layout, ImmutAnyOrigin],
output_data: LayoutTensor[dtype, out_layout, MutAnyOrigin],
size: Int,
):
"""Vector mean normalization using block.sum() + block.broadcast() combination.
This demonstrates the complete block operations workflow:
1. Use block.sum() to compute sum of all elements (all โ one)
2. Thread 0 computes mean = sum / size
3. Use block.broadcast() to share mean to all threads (one โ all)
4. Each thread normalizes: output[i] = input[i] / mean
"""
global_i = Int(block_dim.x * block_idx.x + thread_idx.x)
local_i = thread_idx.x
# Step 1: Each thread loads its element
var my_value: Scalar[dtype] = 0.0
if global_i < size:
my_value = input_data[global_i][0] # Extract SIMD value
# Step 2: Use block.sum() to compute total sum (familiar from earlier!)
total_sum = block.sum[block_size=tpb, broadcast=False](
val=SIMD[DType.float32, 1](my_value)
)
# Step 3: Thread 0 computes mean value
var mean_value: Scalar[dtype] = 1.0 # Default to avoid division by zero
if local_i == 0:
if total_sum[0] > 0.0:
mean_value = total_sum[0] / Float32(size)
# Step 4: block.broadcast() shares mean to ALL threads!
# This completes the block operations trilogy demonstration
broadcasted_mean = block.broadcast[
dtype = DType.float32, width=1, block_size=tpb
](val=SIMD[DType.float32, 1](mean_value), src_thread=UInt(0))
# Step 5: Each thread normalizes by the mean
if global_i < size:
normalized_value = my_value / broadcasted_mean[0]
output_data[global_i] = normalized_value
block.broadcast() ์ปค๋์ ์ธ ๊ฐ์ง ๊ธฐ๋ณธ ํต์ ํจํด์ ๋ชจ๋ ๊ฒฐํฉํ์ฌ ์ํ์ ์ผ๋ก ๊ฒ์ฆ ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ์ค์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์์ ํ ๋ธ๋ก ์ฐ์ฐ ์ํฌํ๋ก์ฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค:
๊ตฌ์ฒด์ ์ธ ์คํ์ ํตํ ์์ ํ ์๊ณ ๋ฆฌ์ฆ ๋ถ์:
1๋จ๊ณ: ๋ณ๋ ฌ ๋ฐ์ดํฐ ๋ก๋ฉ (๋ชจ๋ ์ด์ ํผ์ฆ์์ ํ๋ฆฝ๋ ํจํด)
์ค๋ ๋ ์ธ๋ฑ์ฑ (๋ชจ๋ ํผ์ฆ์์ ์ผ๊ด๋จ):
global_i = block_dim.x * block_idx.x + thread_idx.x // ์
๋ ฅ ๋ฐฐ์ด ์์น์ ๋งคํ
local_i = thread_idx.x // ๋ธ๋ก ๋ด ์์น (0-127)
LayoutTensor ํจํด์ ์ฌ์ฉํ ๋ณ๋ ฌ ์์ ๋ก๋ฉ:
์ค๋ ๋ 0: my_value = input_data[0][0] = 1.0 // ์ฒซ ๋ฒ์งธ ์ํ ๊ฐ
์ค๋ ๋ 1: my_value = input_data[1][0] = 2.0 // ๋ ๋ฒ์งธ ์ํ ๊ฐ
์ค๋ ๋ 7: my_value = input_data[7][0] = 8.0 // ๋ง์ง๋ง ์ํ ๊ฐ
์ค๋ ๋ 8: my_value = input_data[8][0] = 1.0 // ์ํ ๋ฐ๋ณต: 1,2,3,4,5,6,7,8,1,2...
์ค๋ ๋ 15: my_value = input_data[15][0] = 8.0 // 15 % 8 = 7, 8๋ฒ์งธ ๊ฐ
์ค๋ ๋ 127: my_value = input_data[127][0] = 8.0 // 127 % 8 = 7, 8๋ฒ์งธ ๊ฐ
128๊ฐ ์ค๋ ๋๊ฐ ๋์์ ๋ก๋ - ์๋ฒฝํ ๋ณ๋ ฌ ํจ์จ!
2๋จ๊ณ: ๋ธ๋ก ์ ์ฒด ํฉ๊ณ ๋ฆฌ๋์ (์์ ๋ฐฐ์ด block.sum() ์ง์ ํ์ฉ)
128๊ฐ ์ค๋ ๋์ ๊ฑธ์น block.sum() ์กฐ์จ:
๊ธฐ์ฌ๋ถ ๋ถ์:
- ๊ฐ 1,2,3,4,5,6,7,8์ด ๊ฐ๊ฐ 16๋ฒ ๋ฐ๋ณต (128/8 = 16)
- ์ค๋ ๋ ๊ธฐ์ฌ๋ถ: 16ร1 + 16ร2 + 16ร3 + 16ร4 + 16ร5 + 16ร6 + 16ร7 + 16ร8
- ์ํ์ ํฉ๊ณ: 16 ร (1+2+3+4+5+6+7+8) = 16 ร 36 = 576.0
block.sum() ํ๋์จ์ด ์คํ:
๋ชจ๋ ์ค๋ ๋ โ [๋ฆฌ๋์
ํธ๋ฆฌ] โ ์ค๋ ๋ 0
total_sum = SIMD[DType.float32, 1](576.0) // ์ค๋ ๋ 0๋ง ์ด ๊ฐ์ ์์
์ค๋ ๋ 1-127: total_sum์ ์ ๊ทผ ๋ถ๊ฐ (block.sum์์ broadcast=False)
3๋จ๊ณ: ๋ ์ ์ ํ๊ท ๊ณ์ฐ (๋จ์ผ ์ค๋ ๋ ์ฒ๋ฆฌ)
์ค๋ ๋ 0์ด ํต์ฌ ๊ณ์ฐ์ ์ํ:
์
๋ ฅ: total_sum[0] = 576.0, size = 128
๊ณ์ฐ: mean_value = 576.0 / 128.0 = 4.5
๊ฒ์ฆ: ๊ธฐ๋ ํ๊ท = (1+2+3+4+5+6+7+8)/8 = 36/8 = 4.5 โ
๋ค๋ฅธ ๋ชจ๋ ์ค๋ ๋ (1-127):
mean_value = 1.0 (๊ธฐ๋ณธ ์์ ๊ฐ)
์ด ๊ฐ๋ค์ ๋ฌด๊ด - ๋ธ๋ก๋์บ์คํธ๋ก ๋ฎ์ด์์์ง ์์
ํต์ฌ ํต์ฐฐ: ์ด ์์ ์์ ์ฌ๋ฐ๋ฅธ ํ๊ท ๊ฐ์ ๊ฐ์ง ๊ฒ์ ์ค๋ ๋ 0๋ฟ์
๋๋ค!
4๋จ๊ณ: ๋ธ๋ก ์ ์ฒด ๋ธ๋ก๋์บ์คํธ ๋ถ๋ฐฐ (ํ๋ โ ์ ์ฒด ํต์ )
block.broadcast() API ์คํ:
์์ค: src_thread = UInt(0) โ ์ค๋ ๋ 0์ mean_value = 4.5
๋์: ๋ธ๋ก ๋ด ๋ชจ๋ 128 ์ค๋ ๋
๋ธ๋ก๋์บ์คํธ ์ :
์ค๋ ๋ 0: mean_value = 4.5 โ ์ง์ค์ ์์ฒ
์ค๋ ๋ 1: mean_value = 1.0 โ ๋ฎ์ด์์์ง ์์
์ค๋ ๋ 2: mean_value = 1.0 โ ๋ฎ์ด์์์ง ์์
...
์ค๋ ๋ 127: mean_value = 1.0 โ ๋ฎ์ด์์์ง ์์
block.broadcast() ์คํ ํ:
์ค๋ ๋ 0: broadcasted_mean[0] = 4.5 โ ์์ ์ ๊ฐ์ ๋ค์ ์์
์ค๋ ๋ 1: broadcasted_mean[0] = 4.5 โ ์ด์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ ๊ฐ์ง!
์ค๋ ๋ 2: broadcasted_mean[0] = 4.5 โ ์ด์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ ๊ฐ์ง!
...
์ค๋ ๋ 127: broadcasted_mean[0] = 4.5 โ ์ด์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ ๊ฐ์ง!
๊ฒฐ๊ณผ: ์๋ฒฝํ ๋๊ธฐํ - ๋ชจ๋ ์ค๋ ๋๊ฐ ๋์ผํ ํ๊ท ๊ฐ์ ๊ฐ์ง!
5๋จ๊ณ: ๋ณ๋ ฌ ํ๊ท ์ ๊ทํ (์กฐ์จ๋ ์ฒ๋ฆฌ)
๊ฐ ์ค๋ ๋๊ฐ ๋ธ๋ก๋์บ์คํธ๋ ํ๊ท ์ ์ฌ์ฉํ์ฌ ๋
๋ฆฝ์ ์ผ๋ก ์ ๊ทํ:
์ค๋ ๋ 0: normalized = 1.0 / 4.5 = 0.22222222...
์ค๋ ๋ 1: normalized = 2.0 / 4.5 = 0.44444444...
์ค๋ ๋ 2: normalized = 3.0 / 4.5 = 0.66666666...
์ค๋ ๋ 7: normalized = 8.0 / 4.5 = 1.77777777...
์ค๋ ๋ 8: normalized = 1.0 / 4.5 = 0.22222222... (ํจํด ๋ฐ๋ณต)
...
์ํ์ ๊ฒ์ฆ:
์ถ๋ ฅ ํฉ๊ณ = (0.222... + 0.444... + ... + 1.777...) ร 16 = 4.5 ร 16 ร 2 = 128.0
์ถ๋ ฅ ํ๊ท = 128.0 / 128 = 1.0 ์๋ฒฝํ ์ ๊ทํ!
๊ฐ ๊ฐ์ ์๋ ํ๊ท ์ผ๋ก ๋๋๋ฉด ํ๊ท ์ด 1.0์ธ ์ถ๋ ฅ์ ์์ฑ
6๋จ๊ณ: ์ ํ์ฑ ๊ฒ์ฆ
์
๋ ฅ ๋ถ์:
- ํฉ๊ณ: 576.0, ํ๊ท : 4.5
- ์ต๋๊ฐ: 8.0, ์ต์๊ฐ: 1.0
- ๋ฒ์: [1.0, 8.0]
์ถ๋ ฅ ๋ถ์:
- ํฉ๊ณ: 128.0, ํ๊ท : 1.0 โ
- ์ต๋๊ฐ: 1.777..., ์ต์๊ฐ: 0.222...
- ๋ฒ์: [0.222, 1.777] (๋ชจ๋ ๊ฐ์ด 1/4.5 ๋น์จ๋ก ์ค์ผ์ผ๋ง)
๋น๋ก ๊ด๊ณ ๋ณด์กด:
- ์๋ 8:1 ๋น์จ์ด 1.777:0.222 = 8:1๋ก ์ ์ง โ
- ๋ชจ๋ ์๋์ ํฌ๊ธฐ๊ฐ ์๋ฒฝํ๊ฒ ์ ์ง
์ด ์์ ํ ์ํฌํ๋ก์ฐ๊ฐ ์ํ์ ยท๊ณ์ฐ์ ์ผ๋ก ์ฐ์ํ ์ด์ :
๊ธฐ์ ์ ์ ํ์ฑ๊ณผ ๊ฒ์ฆ:
์ํ์ ์ ํ์ฑ ์ฆ๋ช
:
์
๋ ฅ: xโ, xโ, ..., xโ (n = 128)
ํ๊ท : ฮผ = (โxแตข)/n = 576/128 = 4.5
์ ๊ทํ: yแตข = xแตข/ฮผ
์ถ๋ ฅ ํ๊ท : (โyแตข)/n = (โxแตข/ฮผ)/n = (1/ฮผ)(โxแตข)/n = (1/ฮผ)ฮผ = 1 โ
์๊ณ ๋ฆฌ์ฆ์ด ์ฆ๋ช
๊ฐ๋ฅํ๊ฒ ์ฌ๋ฐ๋ฅธ ์ํ์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํฉ๋๋ค.
Puzzle 12 (๊ธฐ์ด ํจํด)๊ณผ์ ์ฐ๊ฒฐ:
- ์ค๋ ๋ ์กฐ์จ์ ์งํ: ๋์ผํ
global_i,local_iํจํด์ด์ง๋ง ๋ธ๋ก ๊ธฐ๋ณธ ์์ ์ฌ์ฉ - ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด: ๋์ผํ LayoutTensor SIMD ์ถ์ถ
[0]์ด์ง๋ง ์ต์ ํ๋ ์ํฌํ๋ก์ฐ - ๋ณต์ก์ฑ ์ ๊ฑฐ: 20์ค ์ด์์ ์๋ ๋ฐฐ๋ฆฌ์ด๋ฅผ 2๊ฐ์ ๋ธ๋ก ์ฐ์ฐ์ผ๋ก ๋์ฒด
- ๊ต์ก์ ์งํ: ์๋ โ ์๋, ๋ณต์ก โ ๋จ์, ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ โ ์ ๋ขฐ์ฑ
block.sum() (์๋ฒฝํ ํตํฉ)๊ณผ์ ์ฐ๊ฒฐ:
- API ์ผ๊ด์ฑ: ๋์ผํ ํ
ํ๋ฆฟ ๊ตฌ์กฐ
[block_size=tpb, broadcast=False] - ๊ฒฐ๊ณผ ํ๋ฆ ์ค๊ณ: ์ค๋ ๋ 0์ด ํฉ๊ณ๋ฅผ ์์ ํ๊ณ , ์์ฐ์ค๋ฝ๊ฒ ํ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ณ์ฐ
- ๋งค๋๋ฌ์ด ์กฐํฉ:
block.sum()์ ์ถ๋ ฅ์ด ๊ณ์ฐ + ๋ธ๋ก๋์บ์คํธ์ ์ ๋ ฅ์ด ๋จ - ์ฑ๋ฅ ์ต์ ํ: ๋จ์ผ ์ปค๋ ์ํฌํ๋ก์ฐ vs ๋ค์ค ํจ์ค ๋ฐฉ์
block.prefix_sum() (์๋ณด์ ํต์ )๊ณผ์ ์ฐ๊ฒฐ:
-
๋ถ๋ฐฐ ํจํด:
prefix_sum์ ๊ณ ์ ํ ์์น๋ฅผ,broadcast๋ ๊ณต์ ๊ฐ์ ์ ๊ณต -
์ฌ์ฉ ์๋๋ฆฌ์ค:
prefix_sum์ ๋ณ๋ ฌ ํํฐ์ ๋์ฉ,broadcast๋ ๋งค๊ฐ๋ณ์ ๊ณต์ ์ฉ -
ํ ํ๋ฆฟ ์ผ๊ด์ฑ: ๋ชจ๋ ์ฐ์ฐ์์ ๋์ผํ
dtype,block_sizeํ๋ผ๋ฏธํฐ ํจํด -
SIMD ์ฒ๋ฆฌ ํต์ผ์ฑ: ๋ชจ๋ ๋ธ๋ก ์ฐ์ฐ์ด
[0]์ถ์ถ์ด ํ์ํ SIMD๋ฅผ ๋ฐํ
๊ณ ๊ธ ์๊ณ ๋ฆฌ์ฆ ์ธ์ฌ์ดํธ:
ํต์ ํจํด ๋น๊ต:
๊ธฐ์กด ๋ฐฉ์:
1. ์๋ ๋ฆฌ๋์
: O(log n), ๋ช
์์ ๋ฐฐ๋ฆฌ์ด ํ์
2. ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ: O(1), ๋๊ธฐํ ํ์
3. ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ: O(1), ๋ฑ
ํฌ ์ถฉ๋ ๊ฐ๋ฅ์ฑ
์ดํฉ: ๋ค์์ ๋๊ธฐํ ์ง์ , ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ
๋ธ๋ก ์ฐ์ฐ ๋ฐฉ์:
1. block.sum(): O(log n), ํ๋์จ์ด ์ต์ ํ, ์๋ ๋ฐฐ๋ฆฌ์ด
2. ๊ณ์ฐ: O(1), ๋จ์ผ ์ค๋ ๋
3. block.broadcast(): O(log n), ํ๋์จ์ด ์ต์ ํ, ์๋ ๋ถ๋ฐฐ
์ดํฉ: ๋ ๊ฐ์ ๊ธฐ๋ณธ ์์, ์๋ ๋๊ธฐํ, ์ฆ๋ช
๋ ์ ํ์ฑ
์ค์ ์์ฉ ์๊ณ ๋ฆฌ์ฆ ํจํด:
์ผ๋ฐ์ ์ธ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ:
1๋จ๊ณ: ๋ณ๋ ฌ ๋ฐ์ดํฐ ์ฒ๋ฆฌ โ ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ธฐ์ฌ
2๋จ๊ณ: ์ ์ญ ํ๋ผ๋ฏธํฐ ๊ณ์ฐ โ ํ๋์ ์ค๋ ๋๊ฐ ๊ณ์ฐ
3๋จ๊ณ: ํ๋ผ๋ฏธํฐ ๋ถ๋ฐฐ โ ๋ชจ๋ ์ค๋ ๋๊ฐ ์์
4๋จ๊ณ: ์กฐ์จ๋ ๋ณ๋ ฌ ์ถ๋ ฅ โ ๋ชจ๋ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌ
์ด ์ ํํ ํจํด์ด ๋ฑ์ฅํ๋ ๋ถ์ผ:
- ๋ฐฐ์น ์ ๊ทํ (๋ฅ๋ฌ๋)
- ํ์คํ ๊ทธ๋จ ๊ท ๋ฑํ (์ด๋ฏธ์ง ์ฒ๋ฆฌ)
- ๋ฐ๋ณต์ ์์น ํด๋ฒ (๊ณผํ ์ฐ์ฐ)
- ์กฐ๋ช
๊ณ์ฐ (์ปดํจํฐ ๊ทธ๋ํฝ)
ํ๊ท ์ ๊ทํ๋ ์ด ๊ทผ๋ณธ์ ์ธ ํจํด์ ์๋ฒฝํ ๊ต์ก ์ฌ๋ก์
๋๋ค.
๋ธ๋ก ์ฐ์ฐ 3๋ถ์ ์์ฑ:
1. block.sum() - ์ ์ฒดโํ๋ (Reduction)
- ์ ๋ ฅ: ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ์ ๊ณต
- ์ถ๋ ฅ: ์ค๋ ๋ 0์ด ์ง๊ณ๋ ๊ฒฐ๊ณผ๋ฅผ ์์
- ์ฉ๋: ํฉ๊ณ, ์ต๋๊ฐ ๊ณ์ฐ ๋ฑ
2. block.prefix_sum() - ์ ์ฒดโ๊ฐ๊ฐ (Scan)
- ์ ๋ ฅ: ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ์ ๊ณต
- ์ถ๋ ฅ: ๊ฐ ์ค๋ ๋๊ฐ ๋์ ์์น๋ฅผ ์์
- ์ฉ๋: ์ฐ๊ธฐ ์์น ๊ณ์ฐ, ๋ณ๋ ฌ ํํฐ์ ๋
3. block.broadcast() - ํ๋โ์ ์ฒด (Broadcast)
- ์ ๋ ฅ: ํ๋์ ์ค๋ ๋๊ฐ ๊ฐ์ ์ ๊ณต (์ผ๋ฐ์ ์ผ๋ก ์ค๋ ๋ 0)
- ์ถ๋ ฅ: ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ๊ฐ์ ์์
- ์ฉ๋: ๊ณ์ฐ๋ ๋งค๊ฐ๋ณ์ ๊ณต์ , ์ค์ ๊ฐ ๋ถ๋ฐฐ
์์ ํ ๋ธ๋ก ์ฐ์ฐ ์งํ:
- ์๋ ์กฐ์จ (Puzzle 12): ๋ณ๋ ฌ ๊ธฐ์ด ์ดํด
- ์ํ ๊ธฐ๋ณธ ์์ (Puzzle 24): ํ๋์จ์ด ๊ฐ์ ํจํด ํ์ต
- ๋ธ๋ก ๋ฆฌ๋์
(
block.sum()): ์ ์ฒดโํ๋ ํต์ ํ์ต - ๋ธ๋ก ์ค์บ (
block.prefix_sum()): ์ ์ฒดโ๊ฐ๊ฐ ํต์ ํ์ต - ๋ธ๋ก ๋ธ๋ก๋์บ์คํธ (
block.broadcast()): ํ๋โ์ ์ฒด ํต์ ํ์ต
์ ์ฒด ๊ทธ๋ฆผ: ๋ธ๋ก ์ฐ์ฐ์ ๊ณ ๊ธ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ํ ๊ธฐ๋ณธ ํต์ ๋น๋ฉ ๋ธ๋ก์ ์ ๊ณตํ๋ฉฐ, ๋ณต์กํ ์๋ ์กฐ์จ์ ๊น๋ํ๊ณ ์กฐํฉ ๊ฐ๋ฅํ ๊ธฐ๋ณธ ์์๋ก ๋์ฒดํฉ๋๋ค.
์ฑ๋ฅ ์ธ์ฌ์ดํธ์ ๊ธฐ์ ๋ถ์
์ ๋์ ์ฑ๋ฅ ๋น๊ต:
block.broadcast() vs ๊ธฐ์กด ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ฐฉ์ (์ฐธ๊ณ ์ฉ):
๊ธฐ์กด ์๋ ๋ฐฉ์:
1๋จ๊ณ: ์๋ ๋ฆฌ๋์
โข ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น: ~5 ์ฌ์ดํด
โข ๋ฐฐ๋ฆฌ์ด ๋๊ธฐํ: ~10 ์ฌ์ดํด
โข ํธ๋ฆฌ ๋ฆฌ๋์
๋ฃจํ: ~15 ์ฌ์ดํด
โข ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅํ ์๋ ์ธ๋ฑ์ฑ
2๋จ๊ณ: ํ๊ท ๊ณ์ฐ: ~2 ์ฌ์ดํด
3๋จ๊ณ: ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก๋์บ์คํธ
โข ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ์ฐ๊ธฐ: ~2 ์ฌ์ดํด
โข ๋ฐฐ๋ฆฌ์ด ๋๊ธฐํ: ~10 ์ฌ์ดํด
โข ๋ชจ๋ ์ค๋ ๋ ์ฝ๊ธฐ: ~3 ์ฌ์ดํด
์ดํฉ: ~47 ์ฌ์ดํด
+ ๋๊ธฐํ ์ค๋ฒํค๋
+ ๊ฒฝ์ ์ํ ๊ฐ๋ฅ์ฑ
+ ์๋ ์ค๋ฅ ๋๋ฒ๊น
๋ธ๋ก ์ฐ์ฐ ๋ฐฉ์:
1๋จ๊ณ: block.sum()
โข ํ๋์จ์ด ์ต์ ํ: ~3 ์ฌ์ดํด
โข ์๋ ๋ฐฐ๋ฆฌ์ด: ๋ช
์์ ๋น์ฉ 0
โข ์ต์ ํ๋ ๋ฆฌ๋์
: ~8 ์ฌ์ดํด
โข ๊ฒ์ฆ๋ ์ฌ๋ฐ๋ฅธ ๊ตฌํ
2๋จ๊ณ: ํ๊ท ๊ณ์ฐ: ~2 ์ฌ์ดํด
3๋จ๊ณ: block.broadcast()
โข ํ๋์จ์ด ์ต์ ํ: ~4 ์ฌ์ดํด
โข ์๋ ๋ถ๋ฐฐ: ๋ช
์์ ๋น์ฉ 0
โข ๊ฒ์ฆ๋ ์ฌ๋ฐ๋ฅธ ๊ตฌํ
์ดํฉ: ~17 ์ฌ์ดํด
+ ์๋ ์ต์ ํ
+ ๋ณด์ฅ๋ ์ ํ์ฑ
+ ์กฐํฉ ๊ฐ๋ฅํ ์ค๊ณ
๋ฉ๋ชจ๋ฆฌ ๊ณ์ธต ๊ตฌ์กฐ ์ด์ :
์บ์ ํจ์จ:
- block.sum(): ์ต์ ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ผ๋ก ์บ์ ๋ฏธ์ค ๊ฐ์
- block.broadcast(): ํจ์จ์ ์ธ ๋ถ๋ฐฐ๋ก ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ ์ฌ์ฉ ์ต์ํ
- ๊ฒฐํฉ ์ํฌํ๋ก์ฐ: ๋จ์ผ ์ปค๋์ด ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์๋ณต์ 100% ๊ฐ์
๋ฉ๋ชจ๋ฆฌ ๋์ญํญ ํ์ฉ:
๊ธฐ์กด ๋ฉํฐ ์ปค๋ ๋ฐฉ์:
์ปค๋ 1: ์
๋ ฅ โ ๋ฆฌ๋์
โ ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ
์ปค๋ 2: ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ โ ๋ธ๋ก๋์บ์คํธ โ ์ถ๋ ฅ
์ด ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์ ์ก: ๋ฐฐ์ด ํฌ๊ธฐ์ 3๋ฐฐ
๋ธ๋ก ์ฐ์ฐ ๋จ์ผ ์ปค๋:
์
๋ ฅ โ block.sum() โ block.broadcast() โ ์ถ๋ ฅ
์ด ์ ์ญ ๋ฉ๋ชจ๋ฆฌ ์ ์ก: ๋ฐฐ์ด ํฌ๊ธฐ์ 2๋ฐฐ (33% ๊ฐ์ )
๊ฐ ๋ธ๋ก ์ฐ์ฐ์ ์ต์ ์ฌ์ฉ ์๋๋ฆฌ์ค:
block.sum() ์ต์ ์๋๋ฆฌ์ค:
- ๋ฐ์ดํฐ ์ง๊ณ: ํฉ๊ณ, ํ๊ท , ์ต๋๊ฐ/์ต์๊ฐ ๊ณ์ฐ
- ๋ฆฌ๋์ ํจํด: ์ ์ฒดโํ๋ ํต์ ์ด ํ์ํ ๋ชจ๋ ๊ฒฝ์ฐ
- ํต๊ณ ์ฐ์ฐ: ํ๊ท , ๋ถ์ฐ, ์๊ด๊ด๊ณ ๊ณ์ฐ
block.prefix_sum() ์ต์ ์๋๋ฆฌ์ค:
- ๋ณ๋ ฌ ํํฐ์ ๋: ์คํธ๋ฆผ ์ปดํฉ์ , ํ์คํ ๊ทธ๋จ ๊ตฌ๊ฐ ๋ถ๋ฅ
- ์ฐ๊ธฐ ์์น ๊ณ์ฐ: ๋ณ๋ ฌ ์ถ๋ ฅ ์์ฑ
- ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ: ์ ๋ ฌ, ๊ฒ์, ๋ฐ์ดํฐ ์ฌ๊ตฌ์ฑ
block.broadcast() ์ต์ ์๋๋ฆฌ์ค:
- ๋งค๊ฐ๋ณ์ ๋ถ๋ฐฐ: ๊ณ์ฐ๋ ๊ฐ์ ๋ชจ๋ ์ค๋ ๋์ ๊ณต์
- ์ค์ ์ ํ: ๋ชจ๋ ํ๋๊ทธ, ์ค์ผ์ผ๋ง ํฉํฐ, ์๊ณ๊ฐ
- ์กฐ์จ๋ ์ฒ๋ฆฌ: ๋ชจ๋ ์ค๋ ๋๊ฐ ๋์ผํ ๊ณ์ฐ๋ ๋งค๊ฐ๋ณ์๊ฐ ํ์ํ ๋
์กฐํฉ์ ์ด์ :
๊ฐ๋ณ ์ฐ์ฐ: ์ข์ ์ฑ๋ฅ, ์ ํ๋ ๋ฒ์
๊ฒฐํฉ ์ฐ์ฐ: ํ์ํ ์ฑ๋ฅ, ํฌ๊ด์ ์ธ ์๊ณ ๋ฆฌ์ฆ
์ค์ ์์ฉ์์ ๋ณผ ์ ์๋ ์กฐํฉ ์์:
โข block.sum() + block.broadcast(): ์ ๊ทํ ์๊ณ ๋ฆฌ์ฆ
โข block.prefix_sum() + block.sum(): ๊ณ ๊ธ ํํฐ์
๋
โข ์ธ ๊ฐ์ง ๋ชจ๋ ๊ฒฐํฉ: ๋ณต์กํ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ
โข ๊ธฐ์กด ํจํด๊ณผ ํจ๊ป: ํ์ด๋ธ๋ฆฌ๋ ์ต์ ํ ์ ๋ต
๋ค์ ๋จ๊ณ
์์ ํ ๋ธ๋ก ์ฐ์ฐ 3๋ถ์์ ๋ฐฐ์ ์ผ๋, ๋ค์์ผ๋ก ์งํํ ์ ์์ต๋๋ค:
- ๋ฉํฐ ๋ธ๋ก ์๊ณ ๋ฆฌ์ฆ: ์ฌ๋ฌ ์ค๋ ๋ ๋ธ๋ก์ ๊ฑธ์น ์ฐ์ฐ ์กฐ์จ
- ๊ณ ๊ธ ๋ณ๋ ฌ ํจํด: ๋ณต์กํ ์๊ณ ๋ฆฌ์ฆ์ ์ํ ๋ธ๋ก ์ฐ์ฐ ๊ฒฐํฉ
- ๋ฉ๋ชจ๋ฆฌ ๊ณ์ธต ๊ตฌ์กฐ ์ต์ ํ: ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ด๋ ํจํด
- ์๊ณ ๋ฆฌ์ฆ ์ค๊ณ: ๋ธ๋ก ์ฐ์ฐ ๋น๋ฉ ๋ธ๋ก์ ์ฌ์ฉํ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐํ
- ์ฑ๋ฅ ์ต์ ํ: ์ต์ ์ ๋ธ๋ก ํฌ๊ธฐ์ ์ฐ์ฐ ์กฐํฉ ์ ํ
๐ก ํต์ฌ ์์ : ๋ธ๋ก ์ฐ์ฐ 3๋ถ์(sum, prefix_sum, broadcast)์ ๋ธ๋ก ๋ ๋ฒจ ๋ณ๋ ฌ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ์์ ํ ํต์ ๊ธฐ๋ณธ ์์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ์ฐ์ฐ๋ค์ ์กฐํฉํ๋ฉด GPU ํ๋์จ์ด ์ต์ ํ๋ฅผ ํ์ฉํ๋ ๊น๋ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ก ๊ณ ๊ธ ๋ณ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ ์ ์์ต๋๋ค. ํ๊ท ์ ๊ทํ๋ ์ด ์ฐ์ฐ๋ค์ด ํจ๊ป ์๋ํ์ฌ ์ค์ ์ฐ์ฐ ๋ฌธ์ ๋ฅผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.