IT story

C ++에서 인라인 함수의 이점은 무엇입니까?

hot-time 2020. 4. 4. 11:02
반응형

C ++에서 인라인 함수의 이점은 무엇입니까?


C ++에서 인라인 함수를 사용할 때의 장점 / 단점은 무엇입니까? 컴파일러가 출력하는 코드의 성능 만 향상 시키지만 오늘날 최적화 된 컴파일러, 빠른 CPU, 대용량 메모리 등 (메모리가 부족하고 모든 것이 100KB의 메모리에 적합해야했던 1980 년과는 다릅니다) 그들은 오늘날 실제로 장점이 있습니까?


인라인 함수는 매개 변수 및 반환 주소와 같이 스택에서 물건을 밀거나 뺄 필요가 없기 때문에 더 빠릅니다. 그러나 바이너리를 약간 크게 만듭니다.

큰 차이가 있습니까? 최신 하드웨어에서는 눈에 띄게 충분하지 않습니다. 그러나 그것은 어떤 사람들에게는 충분한 차이를 만들 수 있습니다.

인라인으로 표시한다고해서 인라인 일 것이라는 보장은 없습니다. 컴파일러에 대한 제안 일뿐입니다. 때로는 가상 기능이 있거나 재귀가 관련된 경우와 같이 불가능할 수도 있습니다. 때로는 컴파일러가 사용하지 않기로 선택하기도합니다.

이와 같은 상황이 감지 가능한 차이를 만드는 것을 볼 수 있습니다.

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

장점

  • 필요한 곳에 코드를 인라인하면 프로그램이 함수 호출 및 리턴 파트에 더 적은 시간을 소비합니다. 코드가 커질수록 코드 속도가 빨라집니다 (아래 참조). 사소한 접근자를 인라인하는 것이 효과적인 인라인의 예일 수 있습니다.
  • 인라인으로 표시하면 헤더 파일에 함수 정의를 넣을 수 있습니다 (예 : 링커가 불평하지 않고 여러 컴파일 단위에 포함될 수 있음).

단점

  • 코드를 더 크게 만들 수 있습니다 (즉, 사소한 기능에 인라인을 사용하는 경우). 따라서 페이징을 유발하고 컴파일러의 최적화를 무효화 할 수 있습니다.
  • 캡슐화는 개체 처리 내부를 노출하기 때문에 캡슐화가 약간 손상됩니다 (그러나 모든 "개인"구성원도 마찬가지입니다). 즉, PImpl 패턴에서 인라인을 사용해서는 안됩니다.
  • 캡슐화가 약간 깨집니다. C ++ 인라이닝은 컴파일 타임에 해결됩니다. 즉, 인라인 함수의 코드를 변경 해야하는 경우 코드를 사용하여 모든 코드를 다시 컴파일해야 업데이트됩니다 (같은 이유로 함수 매개 변수의 기본값은 피함)
  • 헤더에 사용될 때 헤더 파일이 더 커지므로 사용자가 신경 쓰지 않는 코드로 흥미로운 정보 (클래스 메소드 목록과 같은)를 희석합니다 (이것은 내부에서 인라인 함수를 선언하는 이유입니다. 클래스, 클래스 본문 뒤의 헤더에 정의하며 클래스 본문 내부에는 절대 정의하지 않습니다).

인라인 매직

  • 컴파일러는 인라인으로 표시 한 함수를 인라인하거나 인라인하지 않을 수 있습니다. 컴파일 또는 링크 타임에 인라인으로 표시되지 않은 인라인 함수를 결정할 수도 있습니다.
  • 인라인은 컴파일러에 의해 제어되는 복사 / 붙여 넣기와 같이 작동하며 전 처리기 매크로와는 매우 다릅니다. 매크로는 강제로 인라인되고 모든 네임 스페이스와 코드를 오염 시키며 쉽게 디버깅 할 수 없으며 심지어 수행 될 수도 있습니다. 컴파일러가 비효율적 인 것으로 판단했을 경우.
  • 클래스 자체에 정의 된 클래스의 모든 메소드는 "인라인 된"것으로 간주됩니다 (컴파일러가 여전히 인라인하지 않기로 결정할 수 있음
  • 가상 메소드는 피할 수 없습니다. 여전히 컴파일러가 객체의 유형을 확실히 알 수있는 경우 (예 : 객체가 동일한 함수 본문 내에 선언 및 생성 된 경우) 컴파일러가 객체의 유형을 정확히 알고 있기 때문에 가상 함수도 인라인됩니다.
  • 템플릿 메서드 / 함수가 항상 인라인되지는 않습니다 (헤더에 존재하더라도 자동으로 인라인되지는 않습니다).
  • "인라인"다음 단계는 템플릿 메타 프로그래밍입니다. 즉, 컴파일 타임에 코드를 "인라인"하여 컴파일러가 함수의 최종 결과를 추론 할 수 있습니다. 따라서 복잡한 알고리즘을 때로는 일종의 return 42 ;문장 으로 줄일 수 있습니다 . 이것은 나를 위해 극단적 인라이닝 입니다. 실제로는 거의 발생하지 않으며 컴파일 시간이 길어지고 코드가 부풀어지지 않으며 코드가 빨라집니다. 대부분의 처리가이 방법으로 해결 될 수 없기 때문에 그러나 성배처럼 사방을 적용하려고하지 않습니다 ...하지만이 어쨌든 멋지다 ...
    - P

구식 C 및 C ++에서, 가능한 최적화에 대한 컴파일러에 대한 제안 (제안 이상의 것) inline은 다음과 register같습니다.

현대 C ++ inline에서 링커는 선언이 아닌 여러 정의가 다른 번역 단위에서 발견되면 모두 동일하며 링커는 자유롭게 하나를 유지하고 다른 하나는 모두 버릴 수 있습니다.

inline 헤더 파일에 함수 (복잡하거나 "선형")가 정의 된 경우 링커에서 "다중 정의"오류를 발생시키지 않고 여러 소스에 해당 함수를 포함 할 수 있도록하려면 함수가 필수입니다.

클래스 함수 내에 정의 된 멤버 함수는 기본적으로 템플릿 함수와 마찬가지로 "인라인"입니다 (글로벌 함수와 달리).

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

fileA.h를 두 개의 .cpp 파일에 포함 시키면 두 개의 인스턴스가 생성됩니다 afunc(). 링커는 그 중 하나를 버립니다. inline지정 하지 않으면 링커가 불평합니다.


인라이닝은 무시할 수있는 컴파일러에 대한 제안입니다. 작은 코드 비트에 이상적입니다.

함수가 인라인 된 경우 실제로 별도의 함수를 호출하는 대신 함수 호출이 수행되는 코드에 기본적으로 삽입됩니다. 실제 통화를하지 않아도 속도를 높일 수 있습니다.

또한 호출로 인해 새로운 명령으로 파이프 라인을 다시로드 할 필요가 없으므로 CPU가 파이프 라이닝을 지원합니다.

유일한 단점은 이진 크기를 늘릴 수 있다는 것입니다. 그러나 함수가 작을 경우에는 그다지 중요하지 않습니다.

요즘에는 이런 종류의 결정을 컴파일러에 맡기는 경향이 있습니다 (어쨌든 똑똑한 결정). 그것들을 쓴 사람들은 기본 아키텍처에 대해 훨씬 더 자세한 지식을 가지고 있습니다.


인라인 함수는 컴파일러에서 사용하는 최적화 기술입니다. 인라인 키워드를 함수 프로토 타입에 추가하여 함수를 인라인으로 만들 수 있습니다. 인라인 함수는 해당 함수가 코드에서 사용 된 모든 위치에 함수의 완전한 본문을 삽입하도록 컴파일러에 지시합니다.

장점 :-

  1. 함수 호출 오버 헤드가 필요하지 않습니다.

  2. 또한 함수 호출 중에 스택에서 변수 push / pop의 오버 헤드를 저장합니다.

  3. 또한 함수에서 리턴 호출의 오버 헤드를 저장합니다.

  4. 명령 캐시를 활용하여 참조의 지역성을 높입니다.

  5. 인라인 컴파일러가 지정된 경우 절차 내 최적화도 적용 할 수 있습니다. 이것은 컴파일러가 데드 코드 제거에 집중하고 분기 예측, 유도 변수 제거 등에 더 많은 스트레스를 줄 수있는 가장 중요한 방법입니다.

그것에 대한 자세한 내용을 보려면이 링크를 방문하십시오 http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html


공유 라이브러리를 구축 할 때 인라인 함수가 중요하다는 것을 추가하고 싶습니다. 함수를 인라인으로 표시하지 않으면 이진 형식으로 라이브러리로 내보내집니다. 내 보내면 기호 테이블에도 표시됩니다. 반면에 인라인 된 함수는 라이브러리 바이너리 나 기호 테이블로 내 보내지 않습니다.

라이브러리가 런타임에로드 될 때 중요 할 수 있습니다. 이진 호환 인식 라이브러리에 충돌 할 수도 있습니다. 이러한 경우 인라인을 사용하지 마십시오.


최적화하는 동안 많은 컴파일러는 표시하지 않아도 함수를 인라인합니다. 일반적으로 올바른 결정을 내릴 수 있기 때문에 컴파일러가 모르는 것을 알고있는 경우 일반적으로 함수를 인라인으로 표시하면됩니다.


inline#include하나의 정의 규칙을 위반하지 않고 헤더 파일에 함수 정의를 배치하고 해당 헤더 파일을 여러 소스 파일에 배치 할 수 있습니다.


일반적으로 요즘 현대 컴파일러에서 인라인에 대해 걱정하는 것은 시간 낭비입니다. 컴파일러는 자체 코드 분석 및 컴파일러에 전달 된 최적화 플래그 지정을 통해 이러한 모든 고려 사항을 실제로 최적화해야합니다. 속도에 관심이 있다면 속도를 최적화하도록 컴파일러에 지시하십시오. 공간에 관심이 있다면 공간을 최적화하도록 컴파일러에 지시하십시오. 또 다른 대답에서 알 수 있듯이 괜찮은 컴파일러는 실제로 의미가 있다면 자동으로 인라인합니다.

또한 다른 사람들이 언급했듯이 인라인을 사용한다고해서 인라인이 보장되는 것은 아닙니다. 이를 보장하려면 인라인 함수 대신 매크로를 정의해야합니다.

포함을 강제하기 위해 매크로를 인라인 및 / 또는 정의 할 때? -애플리케이션의 전체 성능에 영향을 미치는 것으로 알려진 중요 코드 섹션에 대해 입증되고 필요한 입증 된 속도 증가가있는 경우에만 해당됩니다.


성능에만 관한 것은 아닙니다. C ++과 C는 모두 하드웨어 위에있는 임베디드 프로그래밍에 사용됩니다. 예를 들어, 인터럽트 핸들러를 작성하려면 추가 레지스터 및 / 또는 메모리 페이지를 바꾸지 않고 한 번에 코드를 실행할 수 있는지 확인해야합니다. 인라인이 편리 할 때입니다. 좋은 컴파일러는 속도가 필요할 때 자체적으로 "인라인"을 수행하지만 "인라인"은이를 강제합니다.


라이브러리에 함수를 인라인하는 것과 같은 문제에 빠졌습니다. 인라인 함수는 라이브러리로 컴파일되지 않은 것 같습니다. 결과적으로 실행 파일이 라이브러리의 인라인 함수를 사용하려는 경우 링커에서 "정의되지 않은 참조"오류가 발생합니다. (gcc 4.5로 Qt 소스를 컴파일하는 일이 생겼습니다.


기본적으로 모든 기능을 인라인으로 설정하지 않는 이유는 무엇입니까? 엔지니어링 트레이드 오프이기 때문입니다. "최적화"에는 최소한 두 가지 유형이 있습니다. 프로그램 속도를 높이고 프로그램의 크기 (메모리 공간)를 줄입니다. 인라인은 일반적으로 속도를 높입니다. 스택에서 매개 변수를 밀고 당기는 것을 피하면서 함수 호출 오버 헤드를 제거합니다. 그러나 모든 함수 호출은 이제 함수의 전체 코드로 대체되어야하기 때문에 프로그램의 메모리 풋 프린트가 더 커집니다. 보다 복잡한 작업을 수행하기 위해 CPU는 자주 사용되는 메모리 청크를 CPU의 캐시에 저장하여 매우 빠르게 액세스 할 수 있습니다. 프로그램의 메모리 이미지를 충분히 크게 만들면 프로그램에서 캐시를 효율적으로 사용할 수 없으며 최악의 경우 인라인으로 인해 실제로 프로그램 속도가 느려질 수 있습니다.


우리의 컴퓨터 과학 교수는 C ++ 프로그램에서 인라인을 사용하지 말라고 촉구했습니다. 이유를 물었을 때, 그는 현대 컴파일러가 인라인을 자동으로 사용할시기를 감지해야한다고 친절하게 설명했습니다.

따라서 인라인은 가능한 곳에서 사용되는 최적화 기술이 될 수 있지만 분명히 함수를 인라인 할 수있을 때마다 이미 수행 된 것입니다.


다른 토론 에서 결론 :

인라인 함수의 단점이 있습니까?

인라인 함수를 사용하는 데 아무런 문제가 없습니다.

그러나 다음 사항에 주목할 가치가 있습니다!

  • 인라인을 과도하게 사용하면 실제로 프로그램 속도가 느려질 수 있습니다. 함수의 크기에 따라 인라인하면 코드 크기가 증가하거나 감소 할 수 있습니다. 매우 작은 접근 자 함수를 인라인하면 일반적으로 코드 크기가 줄어들고 매우 큰 함수를 인라인하면 코드 크기가 크게 증가 할 수 있습니다. 최신 프로세서에서는 명령 캐시를 더 잘 사용하기 때문에 일반적으로 작은 코드가 더 빠르게 실행됩니다. -Google 가이드 라인

  • 인라인 함수의 속도 이점은 함수의 크기가 커짐에 따라 감소하는 경향이 있습니다. 어느 시점에서 함수 호출의 오버 헤드가 함수 본문의 실행에 비해 작아지고 이점이 사라집니다 .-소스

  • 인라인 함수가 작동하지 않는 상황은 거의 없습니다.

    • 값을 반환하는 함수의 경우; return 문이 존재하는 경우
    • 값을 반환하지 않는 함수 루프, 스위치 또는 goto 문이 존재하는 경우
    • 함수가 재귀적인 경우 -출처
  • __inline키워드는 최적화 옵션을 지정하는 경우 함수는 인라인됩니다. optimize가 지정되면 __inline인라인 최적화 프로그램 옵션의 설정에 따라 달라집니다. 기본적으로 인라인 옵션은 옵티마이 저가 실행될 때마다 유효합니다. optimize를 지정하면 __inline키워드를 무시 하려면 noinline 옵션도 지정해야합니다 . -출처

참고 URL : https://stackoverflow.com/questions/145838/benefits-of-inline-functions-in-c

반응형