Story-time: C++, bounds checking, performance, and compilers

Story-time: C++, bounds checking, performance, and compilers ๋ฅผ ์ฝ๊ณ .

์š”์•ฝ

์ €์ž๋Š” Chandler Carruth์ด๊ณ  Google์—์„œ Distinguished Software Engineer๋กœ ์ผํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

  1. ๊ณผ๊ฑฐ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ์˜ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ์— ๋Œ€ํ•œ ์˜คํ•ด ์ž‘์„ฑ์ž๋Š” ์ดˆ๊ธฐ์—๋Š” ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋กœ ์ธํ•ด ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ์ €ํ•˜๋  ๊ฒƒ์ด๋ผ๋Š” ํšŒ์˜์ ์ธ ์ž…์žฅ. ์ด๋Š” ๊ณผ๊ฑฐ ๋ณด๊ณ ์„œ๋“ค๊ณผ ๊ฐ„๋‹จํ•œ ์‹คํ—˜ ๊ฒฐ๊ณผ์—์„œ ๋น„๋กฏ๋œ ๋ฏฟ์Œ์ด์—ˆ์œผ๋ฉฐ, ๋‹น์‹œ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ตœ์ ํ™”ํ•˜์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋น„ํ˜„์‹ค์ ์ด๋ผ๊ณ  ์ƒ๊ฐ. ํ•˜์ง€๋งŒ ์ตœ๊ทผ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด, ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ์˜ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์˜ˆ์ƒ๋ณด๋‹ค ๋งค์šฐ ๋‚ฎ๋‹ค๋Š” ์‚ฌ์‹ค์„ ํ™•์ธํ–ˆ์œผ๋ฉฐ, 0.3% ์ˆ˜์ค€์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋กœ๋„ ์ „์ฒด ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํƒ€์ž…์—์„œ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์„ ๊ฐ•์กฐ.

  2. ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ์˜ ํ•„์š”์„ฑ์— ๋Œ€ํ•œ ์ „ํ™˜ ๊ณผ๊ฑฐ์—๋Š” ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๊ฐ€ ๋น„์šฉ์ด ํฌ๋‹ค๊ณ  ๋ฏฟ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ๋…ธ๋ ฅ์ด ๋ถ€์กฑํ–ˆ์ง€๋งŒ, ํ˜„์žฌ๋Š” ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด ํ•„์ˆ˜์ ์ธ ์š”์†Œ๋กœ ์žฌํ‰๊ฐ€. ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ณด์•ˆ ์œ„ํ—˜๊ณผ ์˜ค๋ฅ˜ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด, ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ๋ชจ๋“  ์ฝ”๋“œ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ž…์žฅ์œผ๋กœ ๋ฐ”๋€œ.

  3. ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ ์ตœ์ ํ™”์˜ ๋ฐœ์ „ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ์˜ ์ดˆ๊ธฐ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ด๋ฅผ ์ตœ์ ํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๋Š” ์ ์„ ์ง€์ . C์™€ C++์€ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ถ”์ƒํ™”์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ์„ค๊ณ„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ธํ”„๋ผ๊ฐ€ ๋ถ€์กฑํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ตœ๊ทผ LLVM๊ณผ GCC ๊ฐ™์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐœ์ „ํ–ˆ์œผ๋ฉฐ, ์ด๋Š” ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ์•ˆ์ „์„ฑ๊ณผ ์„ฑ๋Šฅ ๋ชจ๋‘๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ธฐ๋ณธ ์˜ต์…˜์œผ๋กœ ๋งŒ๋“ค ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด์ฃผ์—ˆ์Œ.

๊ธ€์„ ์ฝ๊ณ  ๊ถ๊ธˆํ•œ ๊ฒƒ๋“ค

๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ์ง€์›ํ•˜๋Š” ์–ธ์–ด์™€ ๋„๊ตฌ

  • ์–ธ์–ด ์ฐจ์›
    • Rust, Swift: ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋ฉฐ, ์•ˆ์ „์„ฑ์„ ๊ฐ•์ œ.
    • C, C++: ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜์ง€ ์•Š์œผ๋‚˜, ์ถ”๊ฐ€ ๋„๊ตฌ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ ๊ฐ€๋Šฅ.
  • ๋„๊ตฌ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • AddressSanitizer (ASan): C/C++์—์„œ ๊ฒฝ๊ณ„ ์ดˆ๊ณผ ๋ฌธ์ œ๋ฅผ ์‹คํ–‰ ์‹œ ๊ฐ์ง€.
    • UBSan (Undefined Behavior Sanitizer): ๊ฒฝ๊ณ„ ์ดˆ๊ณผ ์ ‘๊ทผ์„ ํฌํ•จํ•œ ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘ ๊ฐ์ง€.

๊ณต๊ฐ„์  ์•ˆ์ „์„ฑ(Spatial Safety)๊ณผ ์‹œ๊ฐ„์  ์•ˆ์ „์„ฑ(Temporal Safety)

  • ๊ณต๊ฐ„์  ์•ˆ์ „์„ฑ
    • ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์˜ ๊ฒฝ๊ณ„(boundary)์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ
    • ์ด๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ ๋‚ด์—์„œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋„๋ก ๋ณด์žฅํ•˜๋Š” ๊ฐœ๋…
    • ์ฆ‰, ๋ฐฐ์—ด์ด๋‚˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํ• ๋‹น๋œ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„œ๋Š” ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ 
    • ์ฃผ์š” ๋ฌธ์ œ
      • ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ, ๋ฒ„ํผ ์–ธ๋”ํ”Œ๋กœ
    • ํ•ด๋ฒ•
      • ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ, ๋ฉ”๋ชจ๋ฆฌ ๋ณดํ˜ธ ๋„๊ตฌ(Address Sanitizer), ์•ˆ์ „ํ•œ ์–ธ์–ด
  • ์‹œ๊ฐ„์  ์•ˆ์ „์„ฑ
    • ์‹œ๊ฐ„์  ์•ˆ์ „์„ฑ์€ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์˜ ์ˆ˜๋ช…(lifetime)๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•จ.
    • ์ด๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ(์ด๋ฏธ ํ•ด์ œ๋˜์—ˆ๊ฑฐ๋‚˜ ํ• ๋‹น๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ)์— ์ ‘๊ทผํ•˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•˜๋Š” ๊ฐœ๋….
    • ์ฃผ์š” ๋ฌธ์ œ
      • Dangling pointer, Double free, user-after-free
    • ํ•ด๋ฒ•
      • ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ์‚ฌ์šฉ, ์ฐธ์กฐ ์นด์šดํŒ…, ๋™์  ๋ถ„์„ ๋„๊ตฌ(Valgrind), GC,

PGO (Profile-Guided Optimization)์™€ FDO (Feedback-Directed Optimization)๋ž€?

PGO์™€ FDO๋Š” ํ”„๋กœ๊ทธ๋žจ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ•๋ก ์œผ๋กœ, ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์‹œ ์ˆ˜์ง‘๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ตœ์ ํ™”ํ•œ๋‹ค๋Š” ๊ณตํ†ต์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ. ๋‹ค๋งŒ, ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋ชฉ์ ์— ๋”ฐ๋ผ ์ฐจ์ด์ ์ด ์กด์žฌ.

  • PGO (Profile-Guided Optimization)
    • PGO๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ํ”„๋กœํŒŒ์ผ(ํ”„๋กœ๊ทธ๋žจ ๋™์ž‘ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จ)์„ ์‚ฌ์ „์— ์ˆ˜์ง‘ํ•œ ํ›„, ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ตœ์ ํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹.
    • ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ฝ”๋“œ์—์„œ ์ž์ฃผ ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„(ํ•ซ์ŠคํŒŸ)์„ ํŒŒ์•…ํ•˜๊ณ , ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”.
    • ์ž‘๋™ ๋ฐฉ์‹
      • ํ”„๋กœํŒŒ์ผ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
        • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์‹œ ๋‹ค์–‘ํ•œ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์™€ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์‹คํ–‰ํ•˜์—ฌ ํ”„๋กœํŒŒ์ผ ๋ฐ์ดํ„ฐ(์‹คํ–‰ ๋นˆ๋„, ๋ถ„๊ธฐ ํ™•๋ฅ  ๋“ฑ)๋ฅผ ์ˆ˜์ง‘.
      • ํ”„๋กœํŒŒ์ผ ๋ฐ์ดํ„ฐ ๋ถ„์„
        • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ˆ˜์ง‘๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์ž์ฃผ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ์ฝ”๋“œ(์ฝœ๋“œ ์ฝ”๋“œ)๋ฅผ ๊ตฌ๋ถ„.
      • ์ตœ์ ํ™” ์ปดํŒŒ์ผ
        • ํ•ซ์ŠคํŒŸ(์ž์ฃผ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ)์€ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ , ์ฝœ๋“œ ์ฝ”๋“œ(๊ฑฐ์˜ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ)๋Š” ๊ณต๊ฐ„ ํšจ์œจ์„ฑ์„ ๋†’์ด๋„๋ก ์ตœ์ ํ™”.
    • ์˜ˆ์‹œ
      • GCC, LLVM/Clang์˜ -fprofile-generate ๋ฐ -fprofile-use
  • FDO (Feedback-Directed Optimization)
    • FDO๋Š” PGO์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์‹คํ–‰ ์ค‘(runtime) ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ตœ์ ํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋™์  ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด FDO์˜ ํŠน์ง•์ž…๋‹ˆ๋‹ค.
    • ์ž‘๋™ ๋ฐฉ์‹
      • ์‹คํ–‰ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
        • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘ ์ปดํŒŒ์ผ๋Ÿฌ๋‚˜ ๋Ÿฐํƒ€์ž„ ์‹œ์Šคํ…œ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘.
        • ์˜ˆ: ๋ถ„๊ธฐ ์˜ˆ์ธก ์‹คํŒจ, ์บ์‹œ ๋ฏธ์Šค ๋ฐœ์ƒ ๋นˆ๋„ ๋“ฑ.
      • ๋™์  ์ตœ์ ํ™”
        • ๋Ÿฐํƒ€์ž„ ์‹œ์Šคํ…œ์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ , ์ ํ•ฉํ•œ ์ตœ์ ํ™”๋ฅผ ์ ์šฉ.
        • ์ •์ ์œผ๋กœ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ๋„ ์‹คํ–‰ ์ค‘ ๋‹ค์‹œ ์ตœ์ ํ™” ๊ฐ€๋Šฅ.
    • ์˜ˆ์‹œ
      • Java JIT(Just-In-Time) ์ปดํŒŒ์ผ๋Ÿฌ, ์ผ๋ถ€ LLVM ๋Ÿฐํƒ€์ž„ ์ตœ์ ํ™” ๊ธฐ๋ฒ•