๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์ปดํ“จํ„ฐ ๊ตฌ์กฐ & ์šด์˜์ฒด์ œ

[๊ณ ์„ฑ๋Šฅ] Cache Memory์™€ Cache locality(์บ์‹œ ์ง€์—ญ์„ฑ), False sharing(๊ฑฐ์ง“ ๊ณต์œ )

by ์„œ์•„๋ž‘๐Ÿ˜ƒ 2025. 10. 8.

 

๋“ค์–ด๊ฐ€๋ฉฐ

๊ณ ์„ฑ๋Šฅ ์„œ๋น„์Šค๋ฅผ ์œ„ํ•œ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋ณธ ์ค‘์— ๊ธฐ๋ณธ์ธ Cache(์บ์‹œ)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์บ์‹œ๋Š” CPU ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์˜ Cache hit ํ™•๋ฅ ๋งŒ ๋†’์—ฌ์ค˜๋„ ๋งค์šฐ ๋นจ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์— Cache Memory์˜ ์ค‘์š”๋„๋Š” ๋†’๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์บ์‹œ ์ง€์—ญ์„ฑ(Cache Locality)๋ผ๋Š” ๊ฒƒ์€ '์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ž์ฃผ / ์—ฐ์†์ ์œผ๋กœ ์ ‘๊ทผ๋˜๋А๋ƒ'์™€ ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ Cache์— ๋Œ€ํ•ด ์‹ฌ์ธต์ ์œผ๋กœ ํŒŒ์•…ํ•ด๋ด…์‹œ๋‹ค.

 

Cache Memory

ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๊ณ  ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋˜์–ด ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ์™€์„œ ์šด์˜์ฒด์ œ์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์†Œํ”„ํŠธ์›จ์–ด ์ž‘์—…์€ ๋ชจ๋‘ ํ”„๋กœ๊ทธ๋žจ์ด๊ธฐ ๋•Œ๋ฌธ์—(์‹ฌ์ง€์–ด ์šด์˜์ฒด์ œ๋„) ํ”„๋กœ๊ทธ๋žจ ์ž‘๋™ ๋ฐฉ์‹์„ ์•Œ์•„๋‘๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๋Š” CPU์— ์˜ํ•ด ์ž‘์„ฑํ•ด๋‘” ์ฝ”๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” CPU์™€ ๋ฉ”๋ชจ๋ฆฌ(RAM)์€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋–จ์–ด์ ธ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  CPU ์—ฐ์‚ฐ์€ ๋งค์šฐ ๋น ๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ๋ญ๊ฐ€ ๋ฌธ์ œ์ผ๊นŒ์š”? CPU๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๋ถ€๋ถ„์ด ๋А๋ฆฌ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CPU์—์„œ ์—ฐ์‚ฐ 1ํšŒ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์†๋„๋ฅผ ์‚ฌ์ดํด์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ๋น„๊ต์  ์ตœ๊ทผ์— ์ถœ์‹œ๋œ ํ”„๋กœ์„ธ์Šค ๊ธฐ์ค€์œผ๋กœ๋„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ์˜ค๋Š” ๊ฒƒ์€ 40์‚ฌ์ดํด ์ด์ƒ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์ฆ‰, RAM์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋งˆ๋‹ค CPU๋Š” 40ํšŒ ์ด์ƒ์˜ ์—ฐ์‚ฐํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ์œ ํœด์ƒํƒœ๋กœ ๋ณด๋‚ธ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ CPU๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ์บ์‹œ(Cache)๋ผ๋Š” ๊ฒƒ์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์บ์‹œ๋Š” CPU์™€ ๊ทผ์ ‘ํ•œ ๋ฉ”๋ชจ๋ฆฌ์ž…๋‹ˆ๋‹ค. CPU๊ฐ€ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”์ธ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹Œ Cache ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด, ์ฝ๊ธฐ ์†๋„๊ฐ€ ํ˜„์ €ํ•˜๊ฒŒ ์ƒ์Šนํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฉ”์ธ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‚ด์šฉ์„ ๋ชจ๋‘ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ๋„ฃ์œผ๋ฉด ์•ˆ๋ ๊นŒ์š”? ์บ์‹œ์˜ ํฌ๊ธฐ๋Š” ํฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋ž˜๋„ CPU ์นฉ์…‹ ๋‚ด๋ถ€์— ๋“ค์–ด๊ฐ€๋‹ค๋ณด๋‹ˆ CPU์™€ ์ œ์ผ ๊ฐ€๊นŒ์šด ์บ์‹œ๋Š” 100KB๋„ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๊ณ  ์ฝ๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. CPU๊ฐ€ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ์–ด์„œ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์บ์‹œ ํžˆํŠธ(Cache hit)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ์˜ค๋Š˜ ๋‹ค๋ค„๋ณผ ๋‚ด์šฉ์ด ์บ์‹œ ํžˆํŠธ ํ™•๋ฅ ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ๋ฉ๋‹ˆ๋‹ค.

 

๊ณ„์ธต ์˜ˆ์‹œ ์ ‘๊ทผ ์†๋„(ns) ๋น„๊ณ 
L1 Cache Core๋ณ„ 0.5 ~ 1 ๋งค์šฐ ์ž‘๊ณ  ๋น ๋ฆ„
L2 Cache Core๋ณ„ 2 ~ 4 ์ค‘๊ฐ„ ํฌ๊ธฐ
L3 Cache ๊ณต์œ  10 ~ 20 ํฐ ์šฉ๋Ÿ‰, ์—ฌ๋Ÿฌ ์ฝ”์–ด๊ฐ€ ๊ณต์œ 
DRAM Main Memory 60 ~ 120 ์บ์‹œ์— ๋น„ํ•ด ๋งค์šฐ ๋А๋ฆผ

<์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๊ฐœ์š”>

 

CPU์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํƒ์ƒ‰ ์ˆœ์„œ๋Š” L1 ์บ์‹œ -> L2 ์บ์‹œ -> L3 ์บ์‹œ -> ๋ฉ”์ธ๋ฉ”๋ชจ๋ฆฌ ์ˆœ์ž…๋‹ˆ๋‹ค. L1 -> L3๋กœ ๊ฐˆ์ˆ˜๋ก ๋А๋ฆฌ์ง€๋งŒ ์šฉ๋Ÿ‰์€ ์ปค์ง‘๋‹ˆ๋‹ค.

 

Cache Locality

์บ์‹œ์˜ ํšจ์œจ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ž์ฃผ ์ ‘๊ทผ๋˜๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ด๋ฅผ ์ง€์—ญ์„ฑ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์‰ฝ๊ฒŒ ์–˜๊ธฐํ•˜๋ฉด ์บ์‹œ ํžˆํŠธ ํ™•๋ฅ ์— ๊ด€๋ จ๋œ ์šฉ์–ด์ž…๋‹ˆ๋‹ค. ์บ์‹œ ์ง€์—ญ์„ฑ์€ ์‹œ๊ฐ„ ์ง€์—ญ์„ฑ๊ณผ ๊ณต๊ฐ„ ์ง€์—ญ์„ฑ์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

์‹œ๊ฐ„ ์ง€์—ญ์„ฑ(Temporal Locality)

ํ•œ ๋ฒˆ ์ฐธ์กฐ๋œ ์ฃผ์†Œ์˜ ๋‚ด์šฉ์€ ๊ณง ๋‹ค์Œ์— ๋‹ค์‹œ ์ฐธ์กฐ๋œ๋‹ค๋Š” ํŠน์„ฑ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์˜์–ด๋ฅผ ๋ฐฐ์šธ๋•Œ๋„ ๋А๋ผ๋Š” ๊ฒƒ์ด์ง€๋งŒ, ์‚ฌ์šฉํ•˜๋Š” 90%์˜ ๋‹จ์–ด๋Š” ์ƒ์œ„ 1000๊ฐœ ๋‹จ์–ด์— ๊ตญํ•œ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋งค๋ฒˆ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋“ค๋งŒ ์ž์ฃผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋œป์ธ๋ฐ, ํ”„๋กœ๊ทธ๋žจ์—์„œ๋„ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๊ณ„์† ์žฌ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์บ์‹œํ™”ํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ์ธ for, while์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์กฐ๊ฑด ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ํ•œ๋ฒˆ ์ฐธ์กฐ๋œ ๋ฐ์ดํ„ฐ๋Š” ๋˜ ์ฐธ์กฐ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ณต๊ฐ„ ์ง€์—ญ์„ฑ(Spatial Locality)

๊ณต๊ฐ„ ์ง€์—ญ์„ฑ์€ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์— ์—ฐ์†์œผ๋กœ ์ ‘๊ทผํ•  ๋•Œ ์ฐธ์กฐ๋œ ๋ฐ์ดํ„ฐ ๊ทผ์ฒ˜์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žฌ์‚ฌ์šฉ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ๊ณ ์„ฑ๋Šฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ์—๋„ ๋ฉ”๋ชจ๋ฆฌ ์—ฐ์†์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•˜๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

// c++
// first
int res = 0;
for (int i = 0; i < 10000; i++) {
  for (int j = 0; j < 10000; j++) {
    res += data[j];
  }
}


// second
for (int j = 0; j < 10000; j++) {
  for (int i = 0; i < 10000; i++) {
    res += data[j];
  }
}

์œ„์˜ ๊ฒฝ์šฐ first๋ณด๋‹จ second๊ฐ€ ์บ์‹œ ์ง€์—ญ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.second์˜ ๊ฒฝ์šฐ 10,000ํšŒ ๋™์•ˆ ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ์— ์—ฐ์†์œผ๋กœ ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ์ ‘๊ทผ์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์ ‘๊ทผ์ด Cache hit๋˜์–ด์„œ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ์˜ ์„ ์–ธ์—์„œ๋„ int a[10000], b[10000]๊ณผ ๊ฐ™์ด ์„ ์–ธํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์—ฌ๋Ÿฌ ์ค„์— ๋‚˜๋ˆ ์„œ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์บ์‹œ ์ง€์—ญ์„ฑ์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

False Sharing(๊ฑฐ์ง“ ๊ณต์œ )

False Sharing(๊ฑฐ์ง“ ๊ณต์œ )์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ(๋ณ€์ˆ˜)๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐฑ์‹ ํ•˜์ง€๋งŒ,
๊ทธ ๋ฐ์ดํ„ฐ๋“ค์ด ๊ฐ™์€ cache line(๋ณดํ†ต 64 byte)์— ์กด์žฌํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ์ €ํ•˜ ํ˜„์ƒ์ž…๋‹ˆ๋‹ค.
๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ์—ฌ๋Ÿฌ ์ฝ”์–ด๋Š” ์ž์‹ ๋งŒ์˜ ์บ์‹œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ ์ฝ”์–ด์˜ ์บ์‹œ๋ฅผ ๋™๊ธฐํ™” ์‹œ์ผœ์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ฐ™์€ address์— ์ ‘๊ทผํ•จ์—๋„ ๊ฐ ์ฝ”์–ด๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜น์€ ์„œ๋กœ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์ด์ง€๋งŒ ๊ฐ™์€ ์บ์‹œ ๋ผ์ธ์— ์กด์žฌํ•˜์—ฌ ๊ฑฐ์ง“ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์บ์‹œ ๋ผ์ธ์€ ๋ณดํ†ต 64๋ฐ”์ดํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ 64๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ์„ค์ •ํ•ด์ค€๋‹ค๋ฉด ์ฝ”์–ด๋ผ๋ฆฌ ์„œ๋กœ ๋‹ค๋ฅธ ์บ์‹œ ๋ผ์ธ์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋™๊ธฐํ™”๋ฌธ์ œ์—์„œ ์ž์œ ๋กœ์›Œ์ง‘๋‹ˆ๋‹ค. 

// ๋ฌธ์ œ์ƒํ™ฉ
struct Counters {
    std::atomic<int> a;
    std::atomic<int> b;
};

Counters counters;

void thread1() {
    for (int i = 0; i < 1000000; ++i)
        counters.a++;
}

void thread2() {
    for (int i = 0; i < 1000000; ++i)
        counters.b++;
}


// ํ•ด๊ฒฐ(alignas๋ฅผ ํ†ตํ•œ 64๋ฐ”์ดํŠธ ํŒจ๋”ฉ)
struct alignas(64) Counter {
    std::atomic<int> value;
};

Counter c1;
Counter c2;

 

 

Cache ์‚ฌ์šฉ์„ ๊ทน๋Œ€ํ™”ํ•˜๋Š” ์‹ค์ „ ์ „๋žต

1. ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ •๋ ฌ

์„ฑ๋Šฅ์„ ์œ„ํ•ด์„œ๋ผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์—ฐ์†์ ์ธ vector๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค. Linked list๋ฅผ ์‚ฌ์šฉํ•˜๋Š” list์™€ map์€ ์บ์‹œ ๋ฏธ์Šค๊ฐ€ ์žฆ์Šต๋‹ˆ๋‹ค.

// โœ… ์ข‹์€ ์˜ˆ
std::vector<float> v(N);
for (auto &x : v) sum += x;   // spatial locality ์šฐ์ˆ˜

// โŒ ๋‚˜์œ ์˜ˆ
std::list<float> l(N);
for (auto &x : l) sum += x;   // cache miss ๋‹ค๋ฐœ


2. Struct of Arrays (SoA) ํŒจํ„ด

ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ ๋ชจ์•„ ๋ถ„๋ฆฌ๋œ ๋ฐฐ์—ด ๊ตฌ์กฐ(SoA)๋กœ ๊ตฌ์„ฑํ•˜๋ฉด ์บ์‹œ ํšจ์œจ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค.

// โŒ AoS
struct Particle { 
float x, y, z, velocity; 
};

std::vector<Particle> particles;

// โœ… SoA
struct Particles {
    std::vector<float> x, y, z, velocity;
};


3. Loop Reordering (Loop Tiling / Blocking)

๋‹ค์ฐจ์› ๋ฐฐ์—ด์„ ์ˆœํšŒํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ stride ์ ‘๊ทผ์„ ์ตœ์†Œํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// โŒ row-major ๋ฉ”๋ชจ๋ฆฌ์—์„œ column-first ์ ‘๊ทผ
for (int j = 0; j < N; ++j)
  for (int i = 0; i < N; ++i)
    sum += matrix[i][j];

// โœ… row-first ์ ‘๊ทผ
for (int i = 0; i < N; ++i)
  for (int j = 0; j < N; ++j)
    sum += matrix[i][j];


4. False Sharing ๋ฐฉ์ง€

์•ž์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ False sharing์€ ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ฅผ ์•ˆ์“ฐ๋Š” ๊ฒƒ๋งŒ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ ๋ฐฉ์ง€ํ•ด์ค์‹œ๋‹ค. c++์—์„œ๋Š” ์บ์‹œ ๋ผ์ธ์˜ ๋‹จ์œ„์ธ 64๋ฐ”์ดํŠธ๋กœ paddingํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค(alignas ์‚ฌ์šฉ).

struct alignas(64) Counter {
    std::atomic<int> value;
}; // ๊ฐ ์Šค๋ ˆ๋“œ๋ณ„๋กœ cache line ๋ถ„๋ฆฌ

 

 

๋งˆ์น˜๋ฉฐ

๋‹ค์‹œํ•œ๋ฒˆ ๋ง์”€๋“œ๋ฆฌ์ง€๋งŒ ๊ณ ์„ฑ๋Šฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์บ์‹œ ํ™œ์šฉ์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ์–ผ๋งˆ๋“ ์ง€ ์ฝ”๋“œ๋‹จ์—์„œ ์บ์‹œํ™œ์šฉ์„ ๊ทน๋Œ€ํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CPU์™€ ์บ์‹œ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ง•๊ณผ ํ™œ์šฉ๋ฒ•์„ ์•Œ๊ณ  ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ๊ณผ ๋ชจ๋ฅด๊ณ  ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์€ ๋งŽ์ด ๋‹ค๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์„ ์ฝ์€ ์—ฌ๋Ÿฌ๋ถ„๋“ค์€ ์ด์ œ๋ถ€ํ„ฐ ์บ์‹œํ™œ์šฉ๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!
๋‹ค์Œ์‹œ๊ฐ„์—๋Š” Translation Lookaside Buffer(์ผ๋ช… TLB, TLB miss)์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋Œ“๊ธ€