문제

어떤 상황에서는 인라인 함수를 사용하는 것이 매우 편리할 수도 있지만,

인라인 함수에 단점이 있나요?

결론:

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

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

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

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

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

    • 값을 반환하는 함수의 경우;return 문이 존재하는 경우.
    • 값을 반환하지 않는 함수의 경우;루프, 스위치 또는 goto 문이 존재하는 경우.
    • 함수가 재귀적인 경우. -원천
  • 그만큼 __inline 키워드는 최적화 옵션을 지정한 경우에만 함수가 인라인되도록 합니다.최적화가 지정된 경우 여부 __inline 인라인 최적화 옵션의 설정에 따라 적용됩니다.기본적으로 인라인 옵션은 최적화 프로그램이 실행될 때마다 적용됩니다.최적화를 지정하는 경우 다음을 원하면 noinline 옵션도 지정해야 합니다. __inline 무시할 키워드입니다. -원천

도움이 되었습니까?

해결책

inline 키워드는 실제로 컴파일러에 대한 힌트일 뿐이라는 점을 지적할 가치가 있습니다.컴파일러는 인라인을 무시하고 어딘가에 함수에 대한 코드를 생성할 수 있습니다.

인라인 함수의 가장 큰 단점은 실행 파일의 크기를 늘리십시오 (인스턴스화 수에 따라 다름)이는 일부 플랫폼(예:임베디드 시스템), 특히 함수 자체가 재귀적인 경우.

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

다른 팁

실행 파일의 크기를 증가시킬 수 있으며, 인라인 키워드를 사용하더라도 컴파일러가 항상 실제로 인라인으로 만들 것이라고 생각하지 않습니다.(또는 다른 방법은 무엇입니까? 바이바브말했다?...)

함수에 1 ~ 2 개의 진술 만 있으면 일반적으로 괜찮다고 생각합니다.

편집하다: 리눅스는 이렇습니다 코딩 스타일 문서에 따르면 다음과 같습니다.

15장:인라인 질병

GCC가 "Inline"이라는 마법의 "Make Make Me Mess Me Mess Me Mess Me Mess Me Me Mess Me Mess"라는 일반적인 오해가있는 것으로 보입니다.인라인의 사용은 적절할 수 있지만 (예를 들어 매크로를 대체하는 수단으로서 12 장 참조)는 종종 그렇지 않습니다.인라인 키워드를 풍부하게 사용하면 훨씬 더 큰 커널이 발생하여 CPU에 대한 더 큰 ICACHE 발자국으로 인해 시스템이 전체적으로 느려집니다.생각 해보세요;Pagecache Miss는 디스크 찾기를 유발하여 5 마일을 쉽게 사용합니다.이 5 밀리 초로 들어갈 수있는 CPU 사이클이 많이 있습니다.

합리적인 경험 법칙은 3 줄 이상의 코드가있는 기능에 인라인을 넣지 않는 것입니다.이 규칙에 대한 예외는 매개 변수가 컴파일 타임 상수로 알려진 경우이며, 이러한 상수의 결과로 알다 컴파일러는 컴파일 시간에 대부분의 기능을 멀리 최적화 할 수 있습니다.이 후기의 좋은 예는 kmalloc () 인라인 함수를 참조하십시오.

종종 사람들은 정적이고 한 번만 사용되는 기능에 인라인을 추가하는 것이 우주 트레이드 오프가 없기 때문에 항상 승리라고 주장합니다.이것은 기술적으로 정확하지만 GCC는 도움없이 자동으로이를 인라인으로 인쇄 할 수 있으며, 두 번째 사용자가 나타날 때 인라인을 제거하는 유지 보수 문제는 GCC가 어쨌든 수행했을 것이라고 지시하는 힌트의 잠재적 가치를 능가합니다.

다른 게시물에 동의합니다.

  • inline은 컴파일러가 수행하므로 불필요할 수 있습니다.
  • 인라인은 코드를 부풀릴 수 있습니다

세 번째 요점은 헤더에 구현 세부 정보를 노출해야 할 수도 있다는 것입니다.

class OtherObject;

class Object {
public:
    void someFunc(OtherObject& otherObj) {
        otherObj.doIt(); // Yikes requires OtherObj declaration!
    }
};

인라인이 없으면 OtherObject의 전방 선언이 필요한 전부였습니다.인라인을 사용하면 헤더가 다른 개체에 대한 정의가 필요합니다.

다른 사람들이 언급했듯이 inline 키워드는 컴파일러에 대한 힌트일 뿐입니다.실제로 대부분의 최신 컴파일러는 이 힌트를 완전히 무시합니다.컴파일러에는 함수를 인라인할지 여부를 결정하는 자체 경험적 방법이 있으며 솔직히 말해서 귀하의 조언을 원하지 않습니다. 정말 감사합니다.

정말로 무언가를 인라인으로 만들고 싶다면 실제로 프로파일링하고 디스어셈블리를 살펴보며 컴파일러 경험적 방법을 재정의하는 것이 실제로 의미가 있는지 확인했다면 다음과 같이 가능합니다.

  • VC++에서는 __forceinline 키워드를 사용합니다.
  • GCC에서는 __attribute__((always_inline))을 사용합니다.

inline 키워드에는 두 번째로 유효한 목적이 있습니다. 즉, 클래스 정의 내부가 아닌 헤더 파일에서 함수를 선언하는 것입니다.inline 키워드는 컴파일러에게 함수의 여러 정의를 생성하지 않도록 지시하는 데 필요합니다.

인라인에 문제가 있습니다. 헤더 파일에 함수를 정의한 후에는(클래스 내부에 멤버 함수의 본문을 정의하여 명시적이든 암시적이든 인라인을 의미함) 사용자가 다시 컴파일하도록 강요하지 않고 이를 변경할 수 있는 간단한 방법이 없습니다. (다시 연결하는 것과 반대).특히 문제의 함수가 라이브러리에 정의되어 있고 헤더가 해당 인터페이스의 일부인 경우 이로 인해 문제가 발생하는 경우가 많습니다.

나는 그것을 의심한다.심지어 컴파일러도 최적화를 위해 일부 기능을 자동으로 인라인합니다.

내 대답이 질문과 관련이 있는지는 모르겠지만 다음과 같습니다.

BE 매우 인라인 가상 메서드에 주의하세요!일부 버그가 있는 컴파일러(예: 이전 버전의 Visual C++)는 표준 동작이 상속 트리 아래로 내려가 적절한 메서드를 호출하는 것 외에는 아무것도 하지 않는 가상 메서드에 대한 인라인 코드를 생성했습니다.

더 큰 함수를 인라인하면 프로그램이 더 커져서 더 많은 캐시 누락이 발생하고 속도가 느려질 수 있습니다.

인라인이 성능을 향상시킬 만큼 함수가 충분히 작은지를 결정하는 것은 매우 까다롭습니다. Google의 C++ 스타일 가이드 10줄 이하의 인라인 함수만 권장합니다.

또한 inline 키워드는 요청일 뿐이라는 점에 유의해야 합니다.컴파일러는 이를 인라인하지 않도록 선택할 수 있습니다. 마찬가지로 컴파일러는 속도/크기 절충이 가치가 있다고 생각하는 경우 인라인으로 정의하지 않은 함수를 인라인으로 만들도록 선택할 수 있습니다.

이 결정은 일반적으로 속도 최적화(함수 호출 방지)와 크기 최적화(인라인은 코드 팽창을 유발할 수 있으므로 반복적으로 사용되는 대규모 함수에는 적합하지 않음) 간의 설정과 같은 여러 사항을 기반으로 이루어집니다.

VC++ 컴파일러를 사용하면 다음을 사용하여 이 결정을 무시할 수 있습니다. __forceinline

그래서 일반적으로:헤더에 함수를 넣고 싶으면 인라인을 사용하세요. 하지만 다른 곳에서는 별 의미가 없습니다. 왜냐하면 헤더에서 뭔가를 얻으려 한다면 좋은 컴파일러가 어쨌든 함수를 인라인으로 만들어줄 것이기 때문입니다.

과도한 함수 인라인화는 컴파일된 실행 파일의 크기를 증가시켜 캐시 성능에 부정적인 영향을 미칠 수 있지만, 요즘 컴파일러는 자체적으로 함수 인라인화를 결정하고(여러 기준에 따라) 인라인 키워드를 무시합니다.

과도하게 사용되는(500줄의 인라인 함수를 본 적이 있음) 인라인 함수와 관련된 다른 문제 중에서 알아야 할 사항은 다음과 같습니다.

  • 불안정성을 형성하다

    • 인라인 함수의 소스를 변경하면 헤더의 모든 사용자가 다시 컴파일됩니다.
    • #include클라이언트로 누출됩니다.인라인 함수를 재작업하고 일부 클라이언트가 의존했던 더 이상 사용되지 않는 헤더를 제거하는 경우 이는 매우 불쾌할 수 있습니다.
  • 실행 가능한 크기

    • 호출 명령 대신 인라인이 인라인될 때마다 컴파일러는 인라인의 전체 코드를 생성해야 합니다.함수 코드가 짧으면(한두 줄) 괜찮고, 함수가 길면 좋지 않습니다.
    • 일부 함수는 처음에 나타나는 것보다 훨씬 더 많은 코드를 생성할 수 있습니다.제 경우는 Pod가 아닌 멤버 변수(또는 다소 지저분한 소멸자가 있는 2~3개의 멤버 변수)가 많은 클래스의 '사소한' 소멸자입니다.다음에 대한 통화가 생성되어야 합니다. 오물 소각로.
  • 실행 시간

    • 이는 CPU 캐시 및 공유 라이브러리에 따라 크게 다르지만 참조 위치가 중요합니다.인라인할 수 있는 코드가 CPU 캐시 한 곳에 보관되면 많은 클라이언트가 캐시 미스 및 후속 메모리 가져오기(심각한 경우 디스크 가져오기)가 발생하지 않는 코드를 찾을 수 있습니다. .안타깝게도 이는 실제로 성능 분석이 필요한 경우 중 하나입니다.

내가 작업하는 코딩 표준은 인라인 함수를 간단한 setter/getter로 제한하고, 특히 인라인이 눈에 띄는 이점을 제공한다는 것을 보여주는 성능 측정이 없는 한 소멸자가 인라인이 되어서는 안 된다고 말합니다.

  1. 다른 사람들이 말했듯이 인라인 함수는 코드가 크면 문제를 일으킬 수 있습니다. 각 명령이 특정 메모리 위치에 저장되므로 인라인 함수를 오버로드하면 코드가 실행되는 데 더 많은 시간이 걸립니다.

  2. 인라인이 작동하지 않는 다른 상황은 거의 없습니다.

    1. 재귀 함수의 경우에는 작동하지 않습니다.
    2. 정적 변수에서는 작동하지 않을 수도 있습니다.
    3. 루프, 스위치 등을 사용하는 경우에도 작동하지 않습니다. 또는 여러 명령문으로 말할 수 있습니다.
    4. 그리고 main 함수는 인라인 함수로 작동할 수 없습니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top