Post

2026-04-03 TIL (29일차)

2026-04-03 TIL (29일차)

##C++

inline__forceinline

짧은 코드를 가진 함수를 수백, 수천 번 호출해야 할 때 발생하는 성능 저하를 막기 위한 C++의 핵심 최적화 기법에 대해 정리합니다.


일반적인 함수 호출의 숨겨진 비용 (Overhead)

우리가 코드를 짜서 Add(3, 5) 같은 함수를 부르면, CPU는 그냥 뚝딱 계산하는 게 아닙니다. 내부적으로 ‘문맥 교환(Context Switching)’과 비슷한 복잡한 과정을 거칩니다.

비유하자면 “책(메인 코드)을 읽다가, 각주를 확인하려고 책 맨 뒤 페이지(함수)를 폈다가 다시 원래 페이지로 돌아오는 과정과 같습니다.

  • 현재 상태 저장 (Push): 지금 어디까지 실행하고 있었는지, 변수 값은 뭐였는지 메모리(Stack)에 잠시 저장합니다.
  • 점프 (Jump): 함수가 있는 다른 메모리 주소로 접근합니다.
  • 실행: 함수 안의 코드를 실행합니다.
  • 결과 저장 및 복귀 (Pop & Return): 결과값을 챙겨서 아까 저장해 둔 원래 위치로 다시 돌아옵니다.

함수 내용이 아주 길다면 이 과정이 아깝지 않지만, return a + b;처럼 짧은 함수라면 실제 계산하는 시간보다 점프하고 돌아오는 준비 시간이 더 오래 걸리는 일이 벌어집니다.


inline의 마법: “복사 붙여넣기”

이런 낭비를 막기 위해 탄생한 것이 인라인(inline)입니다.

함수 앞에 inline을 붙이면, 컴파일러가 코드를 기계어로 번역할 때 함수를 ‘호출(점프)’하도록 만들지 않습니다. 대신 함수 안에 있는 내용을 함수를 부른 자리에 그대로 ‘복사 붙여넣기(치환)’ 해버립니다. 점프와 복귀 과정이 아예 사라지니 실행 속도가 빨라집니다.


단점: 코드 비대화 (Code Bloat)

“이렇게 빠르면 모든 함수에 다 붙이면 되는 거 아냐?”라고 생각할 수 있지만,

만약 100줄짜리 함수에 inline을 붙이고 그걸 50군데에서 호출한다면 어떻게 될까요? 컴파일러는 100줄짜리 코드를 50군데에 다 복사 붙여넣기 할 것입니다. (코드 길이가 5,000줄로 늘어남)
결과적으로 실행 파일(.exe)의 용량이 엄청 늘어나게되고, 메모리 공간을 많이 차지해서 오히려 CPU 캐시 효율이 떨어져 게임이 더 느려지는 현상이 발생합니다.


inline vs __forceinline 차이

  • inline (제안): 사실 inline 키워드는 컴파일러에게 “이거 인라인으로 만들어주면 좋겠어”라고 부탁(Hint)하는 것에 불과합니다. 현대의 컴파일러는 개발자가 inline을 붙여도 함수 내용이 길면 무시하고 일반 함수로 만들어 버립니다.
  • __forceinline (강제): MSVC(비주얼 스튜디오) 전용 키워드로, 컴파일러의 판단을 깡그리 무시하고 “경고나 에러가 나도 좋으니까 무조건 복사 붙여넣기 해”라고 강제하는 명령어입니다.

C++에서는 보통 헤더 파일(.h)에 함수의 껍데기(선언)만 적고, .cpp에 알맹이(구현)를 적습니다. 하지만 짧은 함수는 헤더 파일에 구현부까지 한 번에 적기도 하는데, 이때 여러 .cpp 파일에서 이 헤더를 include 하면 중복 정의(Multiple Definition) 에러가 발생합니다. 이때 함수 앞에 inline을 붙여주면 링커 에러를 막을 수 있습니다.

게임수학

This post is licensed under CC BY 4.0 by the author.