๐Ÿš€ ์บ์‹œ ์นœํ™”์ ์ธ C ์ฝ”๋“œ ์ž‘์„ฑ๋ฒ•: ์„ฑ๋Šฅ์˜ ๋น„๋ฐ€์„ ํ’€๋‹ค ๐Ÿ”

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ์บ์‹œ ์นœํ™”์ ์ธ C ์ฝ”๋“œ ์ž‘์„ฑ๋ฒ•: ์„ฑ๋Šฅ์˜ ๋น„๋ฐ€์„ ํ’€๋‹ค ๐Ÿ”

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์ฝ”๋”ฉ ๋งˆ๋ฒ•์‚ฌ ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ์•„์ฃผ ํŠน๋ณ„ํ•œ ์—ฌํ–‰์„ ๋– ๋‚˜๋ณผ ๊ฑฐ์˜ˆ์š”. ๋ฐ”๋กœ C ์–ธ์–ด์˜ ์ˆจ๊ฒจ์ง„ ๋ณด๋ฌผ, '์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ๋ฒ•'์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ๋ž๋‹ˆ๋‹ค. ๐Ÿง™โ€โ™‚๏ธโœจ

์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ ํ”„๋กœ๊ทธ๋žจ์ด ๊ฑฐ๋ถ์ด์ฒ˜๋Ÿผ ๋Š๋ฆฌ๊ฒŒ ์›€์ง์ด๋Š” ๊ฒฝํ—˜์„ ํ•ด๋ณด์…จ๋‚˜์š”? ์•„๋‹ˆ๋ฉด ์ปดํ“จํ„ฐ๊ฐ€ ์—ด์„ ๋‚ด๋ฟœ์œผ๋ฉฐ ํž˜๊ฒน๊ฒŒ ๋Œ์•„๊ฐ€๋Š” ๊ฑธ ๋ณธ ์  ์žˆ์œผ์‹ ๊ฐ€์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ์˜ค๋Š˜์˜ ์ฃผ์ œ๋Š” ์—ฌ๋Ÿฌ๋ถ„์—๊ฒŒ ๊ผญ ํ•„์š”ํ•œ ๋งˆ๋ฒ• ์ฃผ๋ฌธ์ด ๋  ๊ฑฐ์˜ˆ์š”!

๐Ÿ’ก ์•Œ๊ณ  ๊ณ„์…จ๋‚˜์š”? ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋งˆ์น˜ ๋กœ์ผ“์ฒ˜๋Ÿผ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

์ž, ๊ทธ๋Ÿผ ์ด์ œ๋ถ€ํ„ฐ C ์–ธ์–ด์˜ ์„ฑ๋Šฅ ๋น„๋ฐ€์„ ํ•˜๋‚˜์”ฉ ํ’€์–ด๋‚˜๊ฐ€ ๋ณผ๊นŒ์š”? ์šฐ๋ฆฌ์˜ ์—ฌ์ •์ด ๋๋‚  ์ฆˆ์Œ์—”, ์—ฌ๋Ÿฌ๋ถ„๋„ ์บ์‹œ์˜ ๋‹ฌ์ธ์ด ๋˜์–ด ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ†

๊ทธ๋ฆฌ๊ณ  ์ž ๊น! ์ด๋Ÿฐ ๋ฉ‹์ง„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ˆ ์„ ๋ฐฐ์šฐ๊ณ  ๋‚˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ์žฌ๋Šฅ์„ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊ณผ ๋‚˜๋ˆ„๊ณ  ์‹ถ์–ด์งˆ ์ˆ˜๋„ ์žˆ์–ด์š”. ๊ทธ๋Ÿด ๋•Œ๋Š” ์žฌ๋Šฅ๋„ท์ด๋ผ๋Š” ํ”Œ๋žซํผ์„ ๊ธฐ์–ตํ•ด๋‘์„ธ์š”. ์—ฌ๊ธฐ์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ์„ ๊ณต์œ ํ•˜๊ณ , ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ์žฌ๋Šฅ๋“ค๋„ ๋งŒ๋‚˜๋ณผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐ŸŒŸ

์ž, ์ด์ œ ์ •๋ง๋กœ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ์บ์‹œ์˜ ์„ธ๊ณ„๋กœ ๋›ฐ์–ด๋“ค ์ค€๋น„ ๋˜์…จ๋‚˜์š”? Let's go! ๐Ÿš€

๐Ÿง  ์บ์‹œ(Cache)๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

์šฐ๋ฆฌ์˜ ์—ฌ์ •์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—, ๋จผ์ € '์บ์‹œ'๋ผ๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณผ ํ•„์š”๊ฐ€ ์žˆ์–ด์š”. ์บ์‹œ๋Š” ๋งˆ์น˜ ์šฐ๋ฆฌ ๋‡Œ์˜ ๋‹จ๊ธฐ ๊ธฐ์–ต์žฅ์น˜์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•œ๋‹ต๋‹ˆ๋‹ค. ๐Ÿง ๐Ÿ’ญ

์บ์‹œ(Cache)์˜ ์ •์˜: ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๋‚˜ ๊ฐ’์„ ์ž„์‹œ๋กœ ์ €์žฅํ•ด๋‘๋Š” ๊ณ ์†์˜ ๊ธฐ์–ต ์žฅ์น˜๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ๋Š” CPU์™€ ์ฃผ ๋ฉ”๋ชจ๋ฆฌ(RAM) ์‚ฌ์ด์— ์œ„์น˜ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๋งˆ์น˜ ํ•™๊ต์—์„œ ์‚ฌ๋ฌผํ•จ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜์ฃ . ์ž์ฃผ ์“ฐ๋Š” ์ฑ…์€ ์‚ฌ๋ฌผํ•จ์— ๋„ฃ์–ด๋‘๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๋น ๋ฅด๊ฒŒ ๊บผ๋‚ด ์“ฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ“š๐Ÿ”‘

์บ์‹œ์˜ ์ข…๋ฅ˜

์บ์‹œ์—๋„ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ต๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์–ด์š”:

  • L1 ์บ์‹œ: CPU์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์ด ์žˆ๋Š” ์บ์‹œ๋กœ, ์†๋„๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฅด์ง€๋งŒ ์šฉ๋Ÿ‰์ด ์ž‘์•„์š”.
  • L2 ์บ์‹œ: L1๋ณด๋‹ค๋Š” ์กฐ๊ธˆ ๋Š๋ฆฌ์ง€๋งŒ, ๋” ํฐ ์šฉ๋Ÿ‰์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”.
  • L3 ์บ์‹œ: ์ผ๋ถ€ ๊ณ ์„ฑ๋Šฅ ํ”„๋กœ์„ธ์„œ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, L2๋ณด๋‹ค ๋” ํฐ ์šฉ๋Ÿ‰์„ ์ œ๊ณตํ•ด์š”.

์ด๋Ÿฐ ์บ์‹œ๋“ค์ด ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•  ๋•Œ, ์šฐ๋ฆฌ์˜ ํ”„๋กœ๊ทธ๋žจ์€ ๋งˆ์น˜ ๋ฒˆ๊ฐœ์ฒ˜๋Ÿผ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! โšก๏ธ

์บ์‹œ๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ 

์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ ์ปดํ“จํ„ฐ๊ฐ€ ๊ณ„์‚ฐ์„ ํ•  ๋•Œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ๊ถ๊ธˆํ•˜์…จ๋‚˜์š”? ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด๋“œ๋ฆด๊ฒŒ์š”:

  1. CPU๊ฐ€ ๋ฐ์ดํ„ฐ๋‚˜ ๋ช…๋ น์–ด๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ–ฅ๏ธ
  2. ๋จผ์ € ์บ์‹œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉ! ๐ŸŽ‰
  3. ์บ์‹œ์— ์—†๋‹ค๋ฉด, ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ(RAM)์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๐Ÿšถโ€โ™‚๏ธ
  4. RAM์—๋„ ์—†๋‹ค๋ฉด, ํ•˜๋“œ ๋””์Šคํฌ์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•ด์š”. ์ด๊ฑด ์ •๋ง ๋Š๋ ค์š”! ๐Ÿข

๋ณด์…จ๋‚˜์š”? ์บ์‹œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์œผ๋ฉด ์—„์ฒญ๋‚˜๊ฒŒ ๋น ๋ฅด๊ฒŒ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ ๊ฑฐ๋ž๋‹ˆ๋‹ค!

๐ŸŒŸ ์žฌ๋Šฅ๋„ท ํŒ: ์บ์‹œ ์ตœ์ ํ™” ๊ธฐ์ˆ ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ถ„์•ผ์—์„œ ๋งค์šฐ ๊ฐ€์น˜ ์žˆ๋Š” ๊ธฐ์ˆ ์ด์—์š”. ์ด๋Ÿฐ ๊ธฐ์ˆ ์„ ์ตํžˆ๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”!

์ž, ์ด์ œ ์บ์‹œ๊ฐ€ ๋ฌด์—‡์ธ์ง€, ์™œ ์ค‘์š”ํ•œ์ง€ ์•Œ๊ฒŒ ๋˜์…จ์ฃ ? ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์‹ค์ œ๋กœ C ์–ธ์–ด์—์„œ ์–ด๋–ป๊ฒŒ ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณด๋„๋ก ํ•ด์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? Let's dive deeper! ๐ŸŠโ€โ™‚๏ธ๐Ÿ’ป

๐Ÿ” C ์–ธ์–ด์—์„œ์˜ ์บ์‹œ ์นœํ™”์  ์ฝ”๋”ฉ: ๊ธฐ๋ณธ ์›์น™

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ C ์–ธ์–ด์—์„œ ์–ด๋–ป๊ฒŒ ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณผ ์‹œ๊ฐ„์ด์—์š”! ๐Ÿ•ต๏ธโ€โ™€๏ธ ์—ฌ๋Ÿฌ๋ถ„, ๋งˆ๋ฒ•์‚ฌ์˜ ์ง€ํŒก์ด๋ฅผ ๊บผ๋‚ด๋“ค ์ค€๋น„๊ฐ€ ๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”?

1. ๋ฐ์ดํ„ฐ ์ง€์—ญ์„ฑ(Data Locality) ํ™œ์šฉํ•˜๊ธฐ

๋ฐ์ดํ„ฐ ์ง€์—ญ์„ฑ์ด๋ž€, ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ€๊นŒ์šด ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์ฃผ ์ ‘๊ทผํ•˜๋Š” ๊ฒฝํ–ฅ์„ ๋งํ•ด์š”. ์ด๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์บ์‹œ ํžˆํŠธ์œจ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

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

์ตœ๊ทผ์— ์ ‘๊ทผํ•œ ๋ฐ์ดํ„ฐ๋Š” ๊ณง ๋‹ค์‹œ ์ ‘๊ทผ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์š”. ์ด๊ฑธ ์‹œ๊ฐ„์  ์ง€์—ญ์„ฑ์ด๋ผ๊ณ  ํ•ด์š”.

์˜ˆ์‹œ: ๋ฃจํ”„์—์„œ ๊ฐ™์€ ๋ณ€์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ


for (int i = 0; i < 1000; i++) {
    sum += data[i];  // 'sum'์€ ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
}

์œ„ ์ฝ”๋“œ์—์„œ 'sum' ๋ณ€์ˆ˜๋Š” ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ์บ์‹œ์— ๊ณ„์† ๋‚จ์•„์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿš€

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

๋ฉ”๋ชจ๋ฆฌ์ƒ์—์„œ ๊ฐ€๊นŒ์ด ์œ„์น˜ํ•œ ๋ฐ์ดํ„ฐ๋“ค์€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์š”. ์ด๊ฑธ ๊ณต๊ฐ„์  ์ง€์—ญ์„ฑ์ด๋ผ๊ณ  ํ•ด์š”.

์˜ˆ์‹œ: ๋ฐฐ์—ด์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ


int arr[1000];
for (int i = 0; i < 1000; i++) {
    arr[i] = i;  // ๋ฐฐ์—ด์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
}

์ด ์ฝ”๋“œ์—์„œ๋Š” ๋ฐฐ์—ด 'arr'์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๊ณ  ์žˆ์–ด์š”. ์บ์‹œ๋Š” ๋ณดํ†ต ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด ์บ์‹œ ํšจ์œจ์ด ๋†’์•„์ง„๋‹ต๋‹ˆ๋‹ค! ๐Ÿ˜Ž

2. ์บ์‹œ ๋ผ์ธ ํฌ๊ธฐ ๊ณ ๋ คํ•˜๊ธฐ

์บ์‹œ๋Š” '์บ์‹œ ๋ผ์ธ'์ด๋ผ๋Š” ๋‹จ์œ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์š”. ๋ณดํ†ต 64๋ฐ”์ดํŠธ ์ •๋„ ๋˜๋Š”๋ฐ, ์ด ํฌ๊ธฐ๋ฅผ ๊ณ ๋ คํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์–ด์š”.

ํŒ: ๊ตฌ์กฐ์ฒด(struct)๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ, ์ž์ฃผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ๋ฉค๋ฒ„๋“ค์„ ๊ฐ€๊นŒ์ด ๋ฐฐ์น˜ํ•˜๊ณ , ์ „์ฒด ํฌ๊ธฐ๋ฅผ ์บ์‹œ ๋ผ์ธ์˜ ๋ฐฐ์ˆ˜์— ๊ฐ€๊น๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”!


// ์ข‹์€ ์˜ˆ:
struct GoodStruct {
    int frequently_used1;
    int frequently_used2;
    char rarely_used[60];  // ํŒจ๋”ฉ์œผ๋กœ ์‚ฌ์šฉ
};  // ์ด 68๋ฐ”์ดํŠธ (64๋ฐ”์ดํŠธ ์บ์‹œ ๋ผ์ธ์— ๊ฐ€๊นŒ์›€)

// ๋‚˜์œ ์˜ˆ:
struct BadStruct {
    int frequently_used1;
    char rarely_used[60];
    int frequently_used2;
};  // ์บ์‹œ ๋ผ์ธ์„ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•จ

'GoodStruct'๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฉค๋ฒ„๋“ค์„ ํ•จ๊ป˜ ๋ฐฐ์น˜ํ•ด์„œ ์บ์‹œ ํšจ์œจ์„ ๋†’์˜€์–ด์š”. ๋ฐ˜๋ฉด 'BadStruct'๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฉค๋ฒ„๋“ค ์‚ฌ์ด์— ํฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์–ด์„œ ์บ์‹œ ํšจ์œจ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

3. ๋ฃจํ”„ ์ตœ์ ํ™”ํ•˜๊ธฐ

๋ฃจํ”„๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ๊ฐ€์žฅ ์‹œ๊ฐ„์„ ๋งŽ์ด ์†Œ๋น„ํ•˜๋Š” ๋ถ€๋ถ„ ์ค‘ ํ•˜๋‚˜์˜ˆ์š”. ๊ทธ๋ž˜์„œ ๋ฃจํ”„๋ฅผ ์ตœ์ ํ™”ํ•˜๋ฉด ์ „์ฒด ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

๋ฃจํ”„ ์–ธ๋กค๋ง (Loop Unrolling)

๋ฃจํ”„ ์–ธ๋กค๋ง์€ ๋ฃจํ”„ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ ํŽผ์ณ์„œ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ ์ค„์ด๋Š” ๊ธฐ๋ฒ•์ด์—์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฃจํ”„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ  ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๊ธฐํšŒ๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ์‹œ: ๋ฃจํ”„ ์–ธ๋กค๋ง ์ ์šฉํ•˜๊ธฐ


// ๊ธฐ๋ณธ ๋ฃจํ”„
for (int i = 0; i < 1000; i++) {
    sum += data[i];
}

// ์–ธ๋กค๋ง ์ ์šฉ
for (int i = 0; i < 1000; i += 4) {
    sum += data[i];
    sum += data[i+1];
    sum += data[i+2];
    sum += data[i+3];
}

์–ธ๋กค๋ง์„ ์ ์šฉํ•œ ๋ฒ„์ „์—์„œ๋Š” ๋ฃจํ”„ ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ 1/4๋กœ ์ค„์–ด๋“ค์—ˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฃจํ”„ ์นด์šดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์กฐ๊ฑด์„ ์ฒดํฌํ•˜๋Š” ํšŸ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค์–ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐ŸŽ๏ธ๐Ÿ’จ

์บ์‹œ ๋ธ”๋กœํ‚น (Cache Blocking)

๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ, ์บ์‹œ ๋ธ”๋กœํ‚น ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์บ์‹œ ํšจ์œจ์„ ํฌ๊ฒŒ ๋†’์ผ ์ˆ˜ ์žˆ์–ด์š”. ์ด ๊ธฐ๋ฒ•์€ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œ ํฌ๊ธฐ์— ๋งž๋Š” ์ž‘์€ ๋ธ”๋ก์œผ๋กœ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด์—์š”.

์˜ˆ์‹œ: ํ–‰๋ ฌ ๊ณฑ์…ˆ์— ์บ์‹œ ๋ธ”๋กœํ‚น ์ ์šฉํ•˜๊ธฐ


#define BLOCK_SIZE 32

void matrix_multiply(int n, double *A, double *B, double *C) {
    for (int i = 0; i < n; i += BLOCK_SIZE) {
        for (int j = 0; j < n; j += BLOCK_SIZE) {
            for (int k = 0; k < n; k += BLOCK_SIZE) {
                // ๋ธ”๋ก ๋‹จ์œ„๋กœ ํ–‰๋ ฌ ๊ณฑ์…ˆ
                for (int ii = i; ii < i + BLOCK_SIZE && ii < n; ++ii) {
                    for (int jj = j; jj < j + BLOCK_SIZE && jj < n; ++jj) {
                        for (int kk = k; kk < k + BLOCK_SIZE && kk < n; ++kk) {
                            C[ii * n + jj] += A[ii * n + kk] * B[kk * n + jj];
                        }
                    }
                }
            }
        }
    }
}

์ด ์˜ˆ์ œ์—์„œ๋Š” ํฐ ํ–‰๋ ฌ์„ 32x32 ํฌ๊ธฐ์˜ ์ž‘์€ ๋ธ”๋ก์œผ๋กœ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ ๋ธ”๋ก์ด ์บ์‹œ์— ์™„์ „ํžˆ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด, ์บ์‹œ ๋ฏธ์Šค๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿงฉโœจ

4. ๋ถ„๊ธฐ ์˜ˆ์ธก ์ตœ์ ํ™”

ํ˜„๋Œ€์˜ CPU๋Š” ๋ถ„๊ธฐ ์˜ˆ์ธก(Branch Prediction)์ด๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ์„ฑ๋Šฅ์„ ๋†’์ด๊ณ  ์žˆ์–ด์š”. ํ•˜์ง€๋งŒ ์˜ˆ์ธก์ด ํ‹€๋ฆฌ๋ฉด ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์ฃ . ๊ทธ๋ž˜์„œ ๊ฐ€๋Šฅํ•˜๋ฉด ๋ถ„๊ธฐ๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.

ํŒ: ์กฐ๊ฑด๋ฌธ ๋Œ€์‹  ๋น„ํŠธ ์—ฐ์‚ฐ์ด๋‚˜ ๋ฃฉ์—… ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”!


// ๋ถ„๊ธฐ๊ฐ€ ๋งŽ์€ ๋ฒ„์ „
int get_sign(int x) {
    if (x > 0) return 1;
    else if (x < 0) return -1;
    else return 0;
}

// ๋ถ„๊ธฐ๋ฅผ ์ œ๊ฑฐํ•œ ๋ฒ„์ „
int get_sign(int x) {
    return (x > 0) - (x < 0);
}

๋‘ ๋ฒˆ์งธ ๋ฒ„์ „์—์„œ๋Š” ์กฐ๊ฑด๋ฌธ ๋Œ€์‹  ์‚ฐ์ˆ  ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด ๋ถ„๊ธฐ๋ฅผ ์ œ๊ฑฐํ–ˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด CPU๊ฐ€ ๋” ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿง โšก

5. ๋ฉ”๋ชจ๋ฆฌ ์ •๋ ฌ (Memory Alignment)

๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•  ๋•Œ, ์ ์ ˆํžˆ ์ •๋ ฌํ•˜๋ฉด ์บ์‹œ ํšจ์œจ์„ ๋†’์ผ ์ˆ˜ ์žˆ์–ด์š”. C์–ธ์–ด์—์„œ๋Š” ๊ตฌ์กฐ์ฒด ๋ฉค๋ฒ„์˜ ์ •๋ ฌ์— ํŠนํžˆ ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”.

์˜ˆ์‹œ: ๊ตฌ์กฐ์ฒด ๋ฉค๋ฒ„ ์ •๋ ฌ ์ตœ์ ํ™”


// ๋น„ํšจ์œจ์ ์ธ ๊ตฌ์กฐ์ฒด
struct BadStruct {
    char a;     // 1๋ฐ”์ดํŠธ
    double b;   // 8๋ฐ”์ดํŠธ
    int c;      // 4๋ฐ”์ดํŠธ
    char d;     // 1๋ฐ”์ดํŠธ
};  // ์ด 24๋ฐ”์ดํŠธ (ํŒจ๋”ฉ ๋•Œ๋ฌธ)

// ์ตœ์ ํ™”๋œ ๊ตฌ์กฐ์ฒด
struct GoodStruct {
    double b;   // 8๋ฐ”์ดํŠธ
    int c;      // 4๋ฐ”์ดํŠธ
    char a;     // 1๋ฐ”์ดํŠธ
    char d;     // 1๋ฐ”์ดํŠธ
    // 2๋ฐ”์ดํŠธ ํŒจ๋”ฉ
};  // ์ด 16๋ฐ”์ดํŠธ

'GoodStruct'๋Š” ๋ฉค๋ฒ„๋“ค์„ ํฌ๊ธฐ ์ˆœ์œผ๋กœ ๋ฐฐ์—ดํ•ด ํŒจ๋”ฉ์„ ์ตœ์†Œํ™”ํ–ˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๋„ ์ค„์ด๊ณ , ์บ์‹œ ํšจ์œจ๋„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿ“ฆโœจ

๐ŸŒŸ ์žฌ๋Šฅ๋„ท ํŒ: ์ด๋Ÿฐ ์ตœ์ ํ™” ๊ธฐ๋ฒ•๋“ค์€ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ๋งค์šฐ ์œ ์šฉํ•ด์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์ด๋Ÿฐ ๊ธฐ์ˆ ์„ ์ตํžˆ๊ณ  ์žฌ๋Šฅ๋„ท์—์„œ ๊ณต์œ ํ•œ๋‹ค๋ฉด, ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”!

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ C ์–ธ์–ด์—์„œ ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ธฐ๋ณธ ์›์น™๋“ค์„ ์•Œ์•„๋ดค์–ด์š”. ์ด ์›์น™๋“ค์„ ์ž˜ ์ ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์€ ๋งˆ์น˜ ์š”์ •์ด ๋งˆ๋ฒ•์„ ๋ถ€๋ฆฐ ๊ฒƒ์ฒ˜๋Ÿผ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿงšโ€โ™‚๏ธโœจ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฐ ์›์น™๋“ค์„ ์‹ค์ œ ์ฝ”๋“œ์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€, ๋” ์ž์„ธํ•œ ์˜ˆ์ œ์™€ ํ•จ๊ป˜ ์‚ดํŽด๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? Let's code like a pro! ๐Ÿ’ป๐Ÿš€

๐Ÿ› ๏ธ ์‹ค์ „ ์˜ˆ์ œ: ์บ์‹œ ์นœํ™”์  C ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ์›์น™๋“ค์„ ์‹ค์ œ ์ฝ”๋“œ์— ์ ์šฉํ•ด๋ณผ ์‹œ๊ฐ„์ด์—์š”! ๐ŸŽจ ์—ฌ๋Ÿฌ๋ถ„, ์ฝ”๋”ฉ ๋ถ“์„ ๋“ค๊ณ  ์บ”๋ฒ„์Šค ์•ž์— ์„œ ์ฃผ์„ธ์š”. ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๋ถ€ํ„ฐ ์บ์‹œ ์นœํ™”์ ์ธ ์ฝ”๋“œ๋ผ๋Š” ๋ฉ‹์ง„ ๊ทธ๋ฆผ์„ ๊ทธ๋ ค๋ณผ ๊ฑฐ์˜ˆ์š”!

1. ๋ฐฐ์—ด ์ˆœํšŒ ์ตœ์ ํ™”

๋ฐฐ์—ด์„ ๋‹ค๋ฃฐ ๋•Œ, ์–ด๋–ป๊ฒŒ ์ˆœํšŒํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์–ด์š”. ํŠนํžˆ 2์ฐจ์› ๋ฐฐ์—ด์„ ๋‹ค๋ฃฐ ๋•Œ ์ด ์ ์ด ์ค‘์š”ํ•ด์š”.

์˜ˆ์ œ: 2์ฐจ์› ๋ฐฐ์—ด ์ˆœํšŒ ์ตœ์ ํ™”


#define N 1000
#define M 1000

// ์บ์‹œ ๋น„ํšจ์œจ์ ์ธ ๋ฒ„์ „
void bad_traverse(int arr[N][M]) {
    for (int j = 0; j < M; j++) {
        for (int i = 0; i < N; i++) {
            arr[i][j]++;  // ์—ด ์šฐ์„  ์ˆœํšŒ
        }
    }
}

// ์บ์‹œ ์นœํ™”์ ์ธ ๋ฒ„์ „
void good_traverse(int arr[N][M]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            arr[i][j]++;  // ํ–‰ ์šฐ์„  ์ˆœํšŒ
        }
    }
}

'good_traverse' ํ•จ์ˆ˜๋Š” ํ–‰ ์šฐ์„ ์œผ๋กœ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•ด์š”. C์–ธ์–ด์—์„œ 2์ฐจ์› ๋ฐฐ์—ด์€ ๋ฉ”๋ชจ๋ฆฌ์— ํ–‰ ์šฐ์„ ์œผ๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๋ฐฉ์‹์ด ์บ์‹œ ์นœํ™”์ ์ด๋ž๋‹ˆ๋‹ค. ๋งˆ์น˜ ์ฑ…์„ ์ฝ์„ ๋•Œ ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ, ์œ„์—์„œ ์•„๋ž˜๋กœ ์ฝ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”! ๐Ÿ“š๐Ÿ‘€

2. ๊ตฌ์กฐ์ฒด ํŒจ๋”ฉ ์ตœ์ ํ™”

๊ตฌ์กฐ์ฒด๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ์ˆœ์„œ๋ฅผ ์ ์ ˆํžˆ ๋ฐฐ์น˜ํ•˜๋ฉด, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ค„์ด๊ณ  ์บ์‹œ ํšจ์œจ์„ ๋†’์ผ ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ์ œ: ๊ตฌ์กฐ์ฒด ํŒจ๋”ฉ ์ตœ์ ํ™”


// ๋น„ํšจ์œจ์ ์ธ ๊ตฌ์กฐ์ฒด
struct BadPerson {
    char name[50];  // 50๋ฐ”์ดํŠธ
    int age;        // 4๋ฐ”์ดํŠธ
    char gender;    // 1๋ฐ”์ดํŠธ
    double salary;  // 8๋ฐ”์ดํŠธ
};  // ์ด 72๋ฐ”์ดํŠธ (ํŒจ๋”ฉ ํฌํ•จ)

// ์ตœ์ ํ™”๋œ ๊ตฌ์กฐ์ฒด
struct GoodPerson {
    char name[50];  // 50๋ฐ”์ดํŠธ
    double salary;  // 8๋ฐ”์ดํŠธ
    int age;        // 4๋ฐ”์ดํŠธ
    char gender;    // 1๋ฐ”์ดํŠธ
    char padding[3];// 3๋ฐ”์ดํŠธ (๋ช…์‹œ์  ํŒจ๋”ฉ)
};  // ์ด 66๋ฐ”์ดํŠธ

'GoodPerson' ๊ตฌ์กฐ์ฒด๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ํฌ๊ธฐ ์ˆœ์œผ๋กœ ๋ฐฐ์—ดํ•˜๊ณ , ๋งˆ์ง€๋ง‰์— ๋ช…์‹œ์  ํŒจ๋”ฉ์„ ์ถ”๊ฐ€ํ–ˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๋„ ์ค„์ด๊ณ  ์บ์‹œ ๋ผ์ธ๋„ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿงฉโœจ

3. ๋ฃจํ”„ ์œตํ•ฉ (Loop Fusion)

์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฃจํ”„๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๋ฉด ์บ์‹œ ์ง€์—ญ์„ฑ์„ ๋†’์ด๊ณ  ๋ฃจํ”„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ์ œ: ๋ฃจํ”„ ์œตํ•ฉ ์ ์šฉ


#define N 10000

// ์œตํ•ฉ ์ „
void before_fusion(int* arr) {
    for (int i = 0; i < N; i++) {
        arr[i] *= 2;
    }
    for (int i = 0; i < N; i++) {
        arr[i] += 5;
    }
}

// ์œตํ•ฉ ํ›„
void after_fusion(int* arr) {
    for (int i = 0; i < N; i++) {
        arr[i] = arr[i] * 2 + 5;
    }
}

'after_fusion' ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ๋ฃจํ”„๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์ณค์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐฐ์—ด 'arr'์„ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ, ์บ์‹œ ํžˆํŠธ์œจ์ด ๋†’์•„์ง€๊ณ  ์‹คํ–‰ ์‹œ๊ฐ„๋„ ์ค„์–ด๋“ค์–ด์š”. ์ผ์„์ด์กฐ๋„ค์š”! ๐ŸŽฏ๐Ÿš€

4. ์กฐ๊ฑด๋ฌธ ์ตœ์ ํ™”

์กฐ๊ฑด๋ฌธ์€ ๋ถ„๊ธฐ ์˜ˆ์ธก์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์กฐ๊ฑด๋ฌธ์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ต๋‹ˆ๋‹ค.

์˜ˆ์ œ: ์กฐ๊ฑด๋ฌธ ์ตœ์  ํ™”


// ์กฐ๊ฑด๋ฌธ ์‚ฌ์šฉ
int abs_with_branch(int x) {
    if (x < 0)
        return -x;
    else
        return x;
}

// ๋น„ํŠธ ์—ฐ์‚ฐ ์‚ฌ์šฉ
int abs_without_branch(int x) {
    int mask = x >> 31;
    return (x ^ mask) - mask;
}

'abs_without_branch' ํ•จ์ˆ˜๋Š” ์กฐ๊ฑด๋ฌธ ๋Œ€์‹  ๋น„ํŠธ ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด์š”. ์ด ๋ฐฉ์‹์€ ๋ถ„๊ธฐ ์˜ˆ์ธก ์‹คํŒจ๋ฅผ ์—†์• ๊ณ  ํŒŒ์ดํ”„๋ผ์ธ ์Šคํ†จ์„ ์ค„์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋งˆ๋ฒ• ๊ฐ™์ฃ ? ๐Ÿง™โ€โ™‚๏ธโœจ

5. ๋ฉ”๋ชจ๋ฆฌ ํ”„๋ฆฌํŽ˜์นญ (Memory Prefetching)

CPU์—๊ฒŒ ๋ฏธ๋ฆฌ ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ• ์ง€ ์•Œ๋ ค์ฃผ๋ฉด, ์บ์‹œ ๋ฏธ์Šค๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”. C์—์„œ๋Š” __builtin_prefetch ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์˜ˆ์ œ: ๋ฉ”๋ชจ๋ฆฌ ํ”„๋ฆฌํŽ˜์นญ ์ ์šฉ


#define N 10000000

void sum_with_prefetch(int* arr, int* result) {
    int sum = 0;
    for (int i = 0; i < N; i++) {
        __builtin_prefetch(&arr[i + 64], 0, 1);  // ๋ฏธ๋ฆฌ 64๊ฐœ ์•ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค
        sum += arr[i];
    }
    *result = sum;
}

์ด ์˜ˆ์ œ์—์„œ๋Š” ํ˜„์žฌ ์ฒ˜๋ฆฌ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ณด๋‹ค 64๊ฐœ ์•ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ค๋„๋ก CPU์—๊ฒŒ ์š”์ฒญํ•˜๊ณ  ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด CPU๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ฏธ๋ž˜๋ฅผ ๋‚ด๋‹ค๋ณด๋Š” ๊ฒƒ ๊ฐ™์ฃ ? ๐Ÿ”ฎ๐Ÿ‘€

6. SIMD (Single Instruction, Multiple Data) ํ™œ์šฉ

ํ˜„๋Œ€ CPU๋Š” SIMD ๋ช…๋ น์–ด๋ฅผ ์ง€์›ํ•ด์š”. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํ•œ ๋ฒˆ์˜ ๋ช…๋ น์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์˜ˆ์ œ: SIMD ๋ช…๋ น์–ด ์‚ฌ์šฉ (GCC ํ™•์žฅ ์‚ฌ์šฉ)


#include <immintrin.h>

void vector_add_simd(float* a, float* b, float* c, int n) {
    for (int i = 0; i < n; i += 8) {
        __m256 va = _mm256_loadu_ps(&a[i]);
        __m256 vb = _mm256_loadu_ps(&b[i]);
        __m256 vc = _mm256_add_ps(va, vb);
        _mm256_storeu_ps(&c[i], vc);
    }
}
</immintrin.h>

์ด ์ฝ”๋“œ๋Š” AVX2 ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด ํ•œ ๋ฒˆ์— 8๊ฐœ์˜ float ๊ฐ’์„ ๋”ํ•ด์š”. ๋งˆ์น˜ 8๊ฐœ์˜ ์†์œผ๋กœ ๋™์‹œ์— ์ผํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ ! ๐Ÿ–๏ธ๐Ÿ–๏ธ

7. ํ•จ์ˆ˜ ์ธ๋ผ์ด๋‹ (Function Inlining)

์ž‘์€ ํ•จ์ˆ˜๋“ค์„ ์ธ๋ผ์ธ์œผ๋กœ ๋งŒ๋“ค๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

์˜ˆ์ œ: ํ•จ์ˆ˜ ์ธ๋ผ์ด๋‹


// ์ธ๋ผ์ธ ํ•จ์ˆ˜ ์ •์˜
static inline int square(int x) {
    return x * x;
}

// ์‚ฌ์šฉ ์˜ˆ
int sum_of_squares(int* arr, int n) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += square(arr[i]);  // ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ด ๋ถ€๋ถ„์„ ์ง์ ‘ x * x๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์–ด์š”
    }
    return sum;
}

'square' ํ•จ์ˆ˜๋ฅผ ์ธ๋ผ์ธ์œผ๋กœ ์ •์˜ํ•˜๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋Œ€์‹  ์ง์ ‘ ๊ณ„์‚ฐ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ๋”ฐ๋ฅธ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿƒโ€โ™‚๏ธ๐Ÿ’จ

๐ŸŒŸ ์žฌ๋Šฅ๋„ท ํŒ: ์ด๋Ÿฐ ์ตœ์ ํ™” ๊ธฐ๋ฒ•๋“ค์€ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ํฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์ด๋Ÿฐ ๊ธฐ์ˆ ๋“ค์„ ์ตํžˆ๊ณ  ์žฌ๋Šฅ๋„ท์—์„œ ๊ณต์œ ํ•œ๋‹ค๋ฉด, ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”. ํŠนํžˆ ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ํŒ€๋“ค์—๊ฒŒ ํฐ ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ๊ฑฐ๋ž๋‹ˆ๋‹ค!

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ์บ์‹œ ์นœํ™”์ ์ธ C ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹ค์ „ ์˜ˆ์ œ๋“ค์„ ์‚ดํŽด๋ดค์–ด์š”. ์ด ๊ธฐ๋ฒ•๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์€ ๋งˆ์น˜ ์Šˆํผ์นด์ฒ˜๋Ÿผ ๋น ๋ฅด๊ฒŒ ๋‹ฌ๋ฆด ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐ŸŽ๏ธ๐Ÿ’จ

ํ•˜์ง€๋งŒ ๊ธฐ์–ตํ•˜์„ธ์š”, ์ตœ์ ํ™”๋Š” ํ•ญ์ƒ ์ธก์ •๊ณผ ํ•จ๊ป˜ ์ด๋ค„์ ธ์•ผ ํ•ด์š”. ๋ฌด์กฐ๊ฑด์ ์ธ ์ตœ์ ํ™”๋ณด๋‹ค๋Š”, ์‹ค์ œ๋กœ ๋ณ‘๋ชฉ์ด ๋˜๋Š” ๋ถ€๋ถ„์„ ์ฐพ์•„ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜๊ณ , ์ •๋ง๋กœ ๊ฐœ์„ ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์— ์ด๋Ÿฐ ๊ธฐ๋ฒ•๋“ค์„ ์ ์šฉํ•ด๋ณด์„ธ์š”.

์—ฌ๋Ÿฌ๋ถ„, ์ด์ œ ์บ์‹œ์˜ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋œ ๊ฒƒ ๊ฐ™์€ ๊ธฐ๋ถ„์ด ๋“ค์ง€ ์•Š๋‚˜์š”? ๐Ÿง™โ€โ™‚๏ธโœจ ์ด ์ง€์‹์„ ๊ฐ€์ง€๊ณ  ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ๋ฉ‹์ง„ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. ๊ทธ๋ฆฌ๊ณ  ์žŠ์ง€ ๋งˆ์„ธ์š”, ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ฒฝํ—˜๊ณผ ์ง€์‹์„ ๊ณต์œ ํ•˜๋ฉด, ๋” ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ•จ๊ป˜ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฐ ์ตœ์ ํ™” ๊ธฐ๋ฒ•๋“ค์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค๊ณผ ํŒ๋“ค์„ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? Let's optimize the world! ๐ŸŒ๐Ÿ’ป

๐ŸŽ“ ์ตœ์ ํ™” ์ ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ ๋ฐ ํŒ

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

1. ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๊ณ ๋ คํ•˜์„ธ์š”

์ตœ์ ํ™”๋Š” ์ค‘์š”ํ•˜์ง€๋งŒ, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํฌ์ƒํ•ด์„œ๋Š” ์•ˆ ๋ผ์š”.

ํŒ: ์ตœ์ ํ™”๋œ ์ฝ”๋“œ์™€ ์›๋ณธ ์ฝ”๋“œ๋ฅผ ํ•จ๊ป˜ ์œ ์ง€ํ•˜๊ณ , ์ฃผ์„์œผ๋กœ ์ตœ์ ํ™” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‚˜์ค‘์— ์ฝ”๋“œ๋ฅผ ๋ณผ ๋•Œ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›Œ์ ธ์š”.


// ์›๋ณธ ์ฝ”๋“œ (์ฃผ์„ ์ฒ˜๋ฆฌ)
/*
for (int i = 0; i < N; i++) {
    result += data[i];
}
*/

// ์ตœ์ ํ™”๋œ ์ฝ”๋“œ
// 4๊ฐœ์”ฉ ๋ฌถ์–ด์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ฃจํ”„ ์–ธ๋กค๋ง ์ ์šฉ
for (int i = 0; i < N; i += 4) {
    result += data[i] + data[i+1] + data[i+2] + data[i+3];
}
// ๋‚จ์€ ์š”์†Œ ์ฒ˜๋ฆฌ
for (int i = (N/4)*4; i < N; i++) {
    result += data[i];
}

2. ํ”„๋กœํŒŒ์ผ๋ง์„ ๋จผ์ € ํ•˜์„ธ์š”

์ตœ์ ํ™”ํ•˜๊ธฐ ์ „์— ํ•ญ์ƒ ํ”„๋กœํŒŒ์ผ๋ง์„ ํ†ตํ•ด ์‹ค์ œ๋กœ ๋ณ‘๋ชฉ์ด ๋˜๋Š” ๋ถ€๋ถ„์„ ์ฐพ์•„์•ผ ํ•ด์š”.

ํŒ: gprof๋‚˜ Valgrind์™€ ๊ฐ™์€ ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์„ธ์š”. ์ด๋Ÿฐ ๋„๊ตฌ๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๊ฐ€์žฅ ์‹œ๊ฐ„์„ ๋งŽ์ด ์†Œ๋น„ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ฐพ์•„์ค„ ๊ฑฐ์˜ˆ์š”.

3. ํ•˜๋“œ์›จ์–ด ํŠน์„ฑ์„ ๊ณ ๋ คํ•˜์„ธ์š”

์บ์‹œ ํฌ๊ธฐ, CPU ์•„ํ‚คํ…์ฒ˜ ๋“ฑ์€ ํ•˜๋“œ์›จ์–ด๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์–ด์š”. ํŠน์ • ํ™˜๊ฒฝ์— ๋งž์ถ˜ ์ตœ์ ํ™”๊ฐ€ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ๋Š” ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

ํŒ: ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋Ÿฐํƒ€์ž„์— ํ•˜๋“œ์›จ์–ด ํŠน์„ฑ์„ ๊ฐ์ง€ํ•˜๊ณ  ๊ทธ์— ๋งž๋Š” ์ตœ์ ํ™”๋ฅผ ์„ ํƒํ•˜๋Š” ๋ฐฉ์‹์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.


#include <cpuid.h>

int has_avx2() {
    unsigned int eax, ebx, ecx, edx;
    __get_cpuid(7, &eax, &ebx, &ecx, &edx);
    return (ebx & bit_AVX2) != 0;
}

void vector_add(float* a, float* b, float* c, int n) {
    if (has_avx2()) {
        vector_add_avx2(a, b, c, n);  // AVX2 ์‚ฌ์šฉ ๋ฒ„์ „
    } else {
        vector_add_scalar(a, b, c, n);  // ์ผ๋ฐ˜ ์Šค์นผ๋ผ ๋ฒ„์ „
    }
}
</cpuid.h>

4. ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”๋ฅผ ํ™œ์šฉํ•˜์„ธ์š”

ํ˜„๋Œ€์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋“ค์€ ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ์ตœ์ ํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์š”. ๋•Œ๋กœ๋Š” ์ˆ˜๋™ ์ตœ์ ํ™”๋ณด๋‹ค ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”๊ฐ€ ๋” ํšจ๊ณผ์ ์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

ํŒ: GCC์˜ -O2๋‚˜ -O3 ์ตœ์ ํ™” ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์„ธ์š”. ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•˜์„ธ์š”, ๋†’์€ ์ˆ˜์ค€์˜ ์ตœ์ ํ™”๋Š” ๊ฐ€๋” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘์„ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.


// ์ปดํŒŒ์ผ ๋ช…๋ น์–ด ์˜ˆ์‹œ
gcc -O3 -march=native myprogram.c -o myprogram

5. ์บ์‹œ ๋ผ์ธ ๊ฒฝ๊ณ„๋ฅผ ๊ณ ๋ คํ•˜์„ธ์š”

๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์บ์‹œ ๋ผ์ธ ํฌ๊ธฐ(๋ณดํ†ต 64๋ฐ”์ดํŠธ)๋ฅผ ๊ณ ๋ คํ•˜๋ฉด ์ข‹์•„์š”.

ํŒ: ์ž์ฃผ ํ•จ๊ป˜ ์ ‘๊ทผ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๊ฐ™์€ ์บ์‹œ ๋ผ์ธ์— ์œ„์น˜ํ•˜๋„๋ก ํ•˜๊ณ , ์„œ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ž์ฃผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋‹ค๋ฅธ ์บ์‹œ ๋ผ์ธ์— ์œ„์น˜ํ•˜๋„๋ก ํ•˜์„ธ์š”.


// ์บ์‹œ ๋ผ์ธ์„ ๊ณ ๋ คํ•œ ๊ตฌ์กฐ์ฒด ์„ค๊ณ„
struct CacheAligned {
    char data[64];  // ์บ์‹œ ๋ผ์ธ ํฌ๊ธฐ๋งŒํผ์˜ ๋ฐ์ดํ„ฐ
} __attribute__((aligned(64)));  // 64๋ฐ”์ดํŠธ ๊ฒฝ๊ณ„์— ์ •๋ ฌ

6. ๊ณผ๋„ํ•œ ์ตœ์ ํ™”๋ฅผ ์ฃผ์˜ํ•˜์„ธ์š”

๋•Œ๋กœ๋Š” '์ถฉ๋ถ„ํžˆ ๋น ๋ฅธ' ์ƒํƒœ์—์„œ ๋ฉˆ์ถ”๋Š” ๊ฒƒ์ด ์ข‹์•„์š”. ๊ณผ๋„ํ•œ ์ตœ์ ํ™”๋Š” ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

ํŒ: ์ตœ์ ํ™”์˜ ๋ชฉํ‘œ๋ฅผ ๋ช…ํ™•ํžˆ ์ •ํ•˜๊ณ , ๊ทธ ๋ชฉํ‘œ์— ๋„๋‹ฌํ•˜๋ฉด ๋ฉˆ์ถ”์„ธ์š”. ์™„๋ฒฝ๋ณด๋‹ค๋Š” '์ถฉ๋ถ„ํžˆ ์ข‹์€' ์ƒํƒœ๋ฅผ ๋ชฉํ‘œ๋กœ ํ•˜์„ธ์š”.

7. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•˜์„ธ์š”

์บ์‹œ ์ตœ์ ํ™” ๊ธฐ๋ฒ• ์ค‘ ์ผ๋ถ€๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ํŠนํžˆ false sharing์— ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”.

ํŒ: ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œ ๋ผ์ธ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.


// False sharing์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์กฐ์ฒด ์„ค๊ณ„
struct ThreadData {
    int data;
    char padding[60];  // ์บ์‹œ ๋ผ์ธ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ์ฑ„์›€
} __attribute__((aligned(64)));

8. ์ตœ์ ํ™” ๊ฒฐ๊ณผ๋ฅผ ํ•ญ์ƒ ์ธก์ •ํ•˜์„ธ์š”

์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ธก์ •ํ•ด์•ผ ํ•ด์š”. ๋•Œ๋กœ๋Š” ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

ํŒ: ๋ฒค์น˜๋งˆํ‚น ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ตœ์ ํ™” ์ „ํ›„์˜ ์„ฑ๋Šฅ์„ ์ •ํ™•ํžˆ ๋น„๊ตํ•˜์„ธ์š”. ์ž‘์€ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‹ค์ œ ์‚ฌ์šฉ ํ™˜๊ฒฝ๊ณผ ์œ ์‚ฌํ•œ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋กœ๋„ ํ…Œ์ŠคํŠธํ•ด๋ณด์„ธ์š”.


#include <time.h>

clock_t start, end;
double cpu_time_used;

start = clock();
// ์ธก์ •ํ•  ์ฝ”๋“œ
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("์‹คํ–‰ ์‹œ๊ฐ„: %f ์ดˆ\n", cpu_time_used);
</time.h>

๐ŸŒŸ ์žฌ๋Šฅ๋„ท ํŒ: ์ตœ์ ํ™” ๊ณผ์ •์—์„œ ์–ป์€ ์ธ์‚ฌ์ดํŠธ์™€ ๊ฒฝํ—˜์„ ์žฌ๋Šฅ๋„ท์—์„œ ๊ณต์œ ํ•ด๋ณด์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ๊ฒช์€ ์‹œํ–‰์ฐฉ์˜ค์™€ ์„ฑ๊ณต ์‚ฌ๋ก€๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”. ํŠนํžˆ ํŠน์ • ๋„๋ฉ”์ธ์ด๋‚˜ ํ™˜๊ฒฝ์—์„œ์˜ ์ตœ์ ํ™” ๊ฒฝํ—˜์€ ๋งค์šฐ ๊ฐ€์น˜ ์žˆ๋Š” ์ •๋ณด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

์ž, ์—ฌ๋Ÿฌ๋ถ„! ์ด์ œ ์บ์‹œ ์นœํ™”์ ์ธ C ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ทธ๊ฒƒ์„ ์‹ค์ œ๋กœ ์ ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค๋„ ์•Œ๊ฒŒ ๋˜์—ˆ์–ด์š”. ์ด ์ง€์‹๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์€ ์„ฑ๋Šฅ์˜ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿง™โ€โ™‚๏ธโœจ

ํ•˜์ง€๋งŒ ๊ธฐ์–ตํ•˜์„ธ์š”. ์ตœ์ ํ™”๋Š” ํ•ญ์ƒ ์ธก์ •, ๋ถ„์„, ๊ฐœ์„ , ๊ฒ€์ฆ์˜ ์ˆœํ™˜ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•ด์š”. ๊ทธ๋ฆฌ๊ณ  ๋•Œ๋กœ๋Š” '์ตœ์ ํ™”ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ'์ด ์ตœ์„ ์˜ ์ตœ์ ํ™”์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ์ฝ”๋“œ์˜ ๋ช…ํ™•์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ•ด์น˜์ง€ ์•Š๋Š” ์„ ์—์„œ, ๊ผญ ํ•„์š”ํ•œ ๊ณณ์— ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•˜์„ธ์š”.

์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ๋น›์˜ ์†๋„๋กœ ๋‹ฌ๋ฆฌ๊ธธ ๋ฐ”๋ž„๊ฒŒ์š”! ๊ทธ๋ฆฌ๊ณ  ์—ฌ๋Ÿฌ๋ถ„์ด ์–ป์€ ๊ท€์ค‘ํ•œ ๊ฒฝํ—˜๋“ค์„ ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๋„ ์žŠ์ง€ ๋งˆ์„ธ์š”. ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€์š”! ๐Ÿš€๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป