inline

inline 키워드는 함수 호출 시 발생하는 오버헤드를 줄이기 위해 함수를 호출하는 대신 함수가 호출되는 곳마다 함수의 코드를 복사해 넣어주는 방법이다.

 

그렇다면 함수 호출 시 발생하는 오버헤드는 뭘까? 실제로 함수가 호출되는 과정을 요약하면

 

  • 함수의 인자를 스택에 저장
  • 함수가 리턴될 때 돌아올 주소를 스택이나 레지스터에 저장
  • 함수의 시작 주소로 점프
  • 함수의 코드 실행
  • 함수에서 만들어진 지역변수, 스택에 저장된 인자 해제, 리턴 값을 레지스터에 저장
  • 함수를 호출 할 때 저장해둔 주소로 되돌아감

 

위와 같은 과정을 거치는데 간단한 함수를 호출하기 위해서 저런 명령어들을 수행해야 한다면 오버헤드가 될 수밖에 없다. 이런 오버 헤드를 줄이기 위해 C++에서는 inline이라는 키워드를 제공한다.

 

[그림 1. 일반 함수와 인라인 함수의 차이]

 

그림과 같이 함수 호출 과정 없이 코드를 그대로 복제하여 넣어주므로 속도가 더 빠르다. 단, 코드를 그대로 복제한 만큼 실행 파일의 크기가 커지는 단점이 있다.

 

inline 키워드는 권장 사항일 뿐 컴파일러는 프로그래머가 inline 키워드를 선언해도 자유롭게 무시할 수 있다. (긴 함수를 inline화 하려고 하면 무시할 가능성이 있다)
반대로  프로그래머가 inline을 선언 안해도 컴파일러가 성능을 위해 inline화 시킬 수도 있다.

 

__inline

inline과 동일한 기능을 수행한다. 단, inline은 C++ 전용 키워드지만 __inline은 C에서도 사용할 수 있다.

 

 

__forceinline

 __forceinline 키워드는 컴파일러의 비용/이익 분석을 무시하고 프로그래머의 판단에 의존한다. 그렇기 때문에 무분별한 사용은 코드가 커지고 성능 향상은 미미할 수 있다.

 

 __forceinline 키워드를 사용해도 특정 함수를 강제로 inline화 시킬 수 없는 경우가 있다.

  • 함수 또는 호출대상이 /Ob0(디버그 빌드 기본값) 컴파일 옵션으로 컴파일된 경우
  • 함수 또는 호출대상이 서로 다른 형식의 예외 처리를 사용하는 경우
    (예 : 한쪽은 C++ 예외처리, 다른 쪽은 구조화된 예외처리를 사용하는 경우)
  • 함수가 가변인수 리스트를 가지고 있는 경우
  • 함수가 /Og, /Ox, /O1 또는 /O2를 쓰지 않고 인라인 어셈블리를 사용하는 경우
  • 함수가 재귀적이고 #pragma inline_recursion(on)을 하지 않은 경우.
    Pragma 재귀함수는 총 16번의 깊이로 인라인 한다. 깊이를 조절하려면 #pragma inline_depth를 사용하면 된다.
  • 함수가 virtual이고 가상적으로 호출되는 경우, 가상함수의 직접 호출은 인라인 가능.
  • 프로그램에서 해당 함수의 주소를 사용하는 함수 포인터로 호출될 경우.
  • 주소가 있었던 해당 함수에 대한 직접 호출의 경우 인라인 가능.
  • naked_declspec로 수식된 함수의 경우.

'DevLog > C & C++' 카테고리의 다른 글

C++ 스마트포인터  (0) 2021.01.23
C++ 다형성과 가상함수  (0) 2021.01.22
Visual Assist 한글 주석 빨간줄 제거 방법  (0) 2018.01.15
이스케이프 시퀀스  (0) 2017.12.26
Pro *C 사용방법  (0) 2017.11.30
복사했습니다!