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을 붙여주면 링커 에러를 막을 수 있습니다.