본문 바로가기

인라인 함수 (Inline Functions) 본문

💘 C++/함수

인라인 함수 (Inline Functions)

Hyonii 2022. 7. 31. 16:12

인라인 함수 (Inline Functions)

함수를 사용하면 다음과 같은 많은 이점을 얻을 수 있다.

 

  • 함수 내부의 코드를 재사용할 수 있다.
  • 인스턴트 코드보다 함수에서 코드를 변경하거나 업데이트하기가 더 쉽다
  • 함수 이름을 통해 코드가 무엇을 의미하는지 이해하기 더 쉽다.
  • 함수는 함수 호출 인수가 함수 매개 변수와 일치하는지 확인하기 위해 타입 검사를 한다. (매크로는 안 한다.)
  • 함수는 프로그램을 디버그 하기 쉽게 만든다.

그러나 함수는 함수가 호출될 때마다 발생하는 일정량의 성능 오버헤드가 있다는 단점이 있다.

이는 CPU가 다른 레지스터와 함께 실행 중인 현재 명령어의 주소를 저장해야 하므로(나중에 반환할 위치를 알 수 있도록)
모든 함수 매개 변수를 생성해야 한다.

할당된 값을 사용하면 프로그램이 새 위치로 분기된다.

내부에서 작성된 코드(인스턴트 코드)가 훨씬 더 빠르다.

 

크거나 복잡한 태스크를 수행하는 함수의 경우

함수 호출의 오버헤드는 함수가 실행되는 데 걸리는 시간과 비교할 때 중요하지 않다.

그러나 일반적으로는 사용하는 작은 함수의 경우,

함수 호출에 필요한 시간이 실제로 함수 코드를 실행하는 데 필요한 시간보다 훨씬 많은 경우가 있다.

이로 인해 상당한 성능 저하가 발생할 수 있다.

 

C++은 인라인 함수(Inline Function)라는 내부에서 작성된 코드의 속도와 함수의 장점을 결합하는 방법을 제공한다.

inline 키워드는 컴파일러에서 함수를 인라인 함수로 처리하도록 요청한다.

컴파일러가 코드를 컴파일하면 모든 인라인 함수가 인-플레이스(in-place) 확장된다.

즉, 함수 호출이 함수 자체의 내용 복사본으로 대체되어 함수 오버헤드가 제거된다.

단점은 인라인 함수가 모든 함수 호출에 대해 적절한 위치에서 확장되므로

인라인 함수가 길거나 인라인 함수를 여러 번 호출하는 경우 컴파일된 코드를 약간 더 크게 만들 수 있다는 것이다.

 

예제를 통해 인라인 함수에 대해 알아보자

 

아주 간단한 함수를 하나 만들었다.

정수 x와 y 두 개를 받고,

둘 중에 작은 값을 리턴해주는 함수이다.

조건부 연산자 기억 안 나면 ↓ 참고하기

 

Sizeof, 쉼표 연산자, 조건부 연산자

Sizeof Operator 어떠한 데이터형의 크기를 알고 싶을 때 사용. sizeof 연산자는 자료형 또는 변수를 가지고 크기를 byte 단위로 반환하는 연산자다. 특정 시스템에서 자료형의 크기를 결정하기 위해 C++

hyoniidaaa.tistory.com

이 min 함수를 main에서 사용한다고 생각해보자.

 

프로그램이 실행되면서 먼저 min 함수가 호출된다.

어딘가에 저장되어있다가 min 함수의 실행코드를 가져오고

그거에 따라서 실행하라는 명령이 떨어진다.

그럼 그걸 가져오고 변수 x와 y를 선언하고

값 5,6을 복사를 하고

그다음 x > y ? y : x; 이 부분을 실행을 시키고

그다음에 return을 해주고

받아오는 곳에서 값을 받아오고

그것을 출력을 하는 이러한 일련의 과정이 벌어진다.

 

이런 작은 함수가 아주 많이 반복되는 경우도 있다.

그래서 어떤 경우에는 실제 계산하는 부분 (x > y ? y : x;) 보다

지금 말씀드린 일련의 과정들이 더 시간이 많이 걸릴 때도 있다.

그래서 그 과정을 줄이기 위해서 인라인 함수라는 것을 사용을 할 때가 있다,

 

어떻게 사용하냐면

그냥 앞에다가 inline이라고 써주면 된다.

 

간단하다.

보통 헤더 파일에 함수를 정의할 때 많이 사용한다.

그다음에 오픈소스 코드를 보면 굉장히 많은 함수들을 거의 다 inline으로 칠해놓는 경우가 있다.

inline으로 바꾸게 되면 사실 얘는 함수가 아닌 것처럼 작동을 한다.

 

.x > y ? y : x; 이 코드를 (5 > 6 ? 6 : 5) 이렇게 작성된 것 처럼 컴파일이 된다.

컴파일러가 봤을 때 아 얘가 인라인이니까 이렇게 넣어주자는 식으로 작동한다.

(5 > 6 ? 6 : 5) 이렇게 되어있으면 함수가 호출될 일도 없고

local variable인 x, y가 선언될 일도 없고 삭제될 일도 없어서 빠르다.

그래서 많은 프로그래머들이 인라인 함수를 많이 사용을 하는 경우가 있다.

 

그런데 인라인 함수를 실제 사용하기에 앞서 알아야 하는 사실이 있다.

이 inline 키워드는 강제로 이 함수를 무조건 inline으로 해라라고 해서 만든 게 아니고

이렇게 할 수 있으면 해 주세요~라고 권유하는 뉘앙스다.

inline 키워드는 권장 사항일 뿐이다.

컴파일러는 인라인에 대한 요청을 자유롭게 무시할 수 있다.( 긴 함수를 인라인화 하려고 하면 무시할 가능성이 있다.)

그래서 컴파일러가 딱 봤을 때 아 얘는 인라인을 쓰면 좋을 것 같네? 생각해 보는 정도가 되는 거다.

그래서 모든 함수를 inline으로 바꾼다고 해서 빨라지는 것은 절대 아니다.

 

그리고 최근에는 컴파일러가 아주 좋아져서

inline이 없어도 자기가 생각할 때 논리적으로 따져봤을 때

아 여기에 inline 넣으면 아주 빨라지겠네? 싶으면 자기가 알아서 인라인 화한다.

inline을 쓴다고 해서 빨라지는 보장도 없고 안 쓴다고 안 빨라지는 보장도 없다는 식으로 얘기가 나오고 있다.

아무튼 코딩할 때 inline에 의존해서 최적화를 하기 시작하면 좀 힘들어진다.

 

인라인은 사용법이 간단하지만

더 중요한 것은 컴파일러가 진짜 해줄지 안 해줄지는 알기 어렵다는 것이다.

또 한 가지 단점은 만약 min 같은 inline으로 된 함수가 엄청 많고

컴파일러가 정말 inline으로 구현을 했다면 컴파일된 프로그램이 많이 커진다.

프로그램이 커지면 어쨌든 그 안에서 데이터가 왔다 갔다 하는데 더 많은 시간이 걸리기 때문에

코드가 너무 커져서 인라인을 사용한 효과를 못 보게 될 수도 있다.

코드를 부풀릴 가능성이 있으므로 함수를 인라인화 하는 것은 내부 루프가 없는 짧은 함수에 가장 적합하다.

 

인라인 문법에 대해서는 말씀드렸으나 사용하는 게 확실히 좋다 권장한다 이렇게는 말씀드리기 어렵다.

Comments