Programing

인라인 기능 사용시기와 사용하지 않을시기

crosscheck 2020. 5. 25. 21:03
반응형

인라인 기능 사용시기와 사용하지 않을시기


인라인은 컴파일러에 대한 힌트 또는 요청이며 함수 호출 오버 헤드를 피하는 데 사용됩니다.

따라서 함수가 인라인 후보인지 여부를 어떤 기준으로 결정할 수 있습니까? 어떤 경우에는 인라인을 피해야합니까?


함수 호출 비용을 피하는 것은 이야기의 절반에 지나지 않습니다.

하다:

  • inline대신에 사용#define
  • 매우 작은 함수는 inline다음과 같은 대상에 적합합니다 . 빠른 코드와 작은 실행 파일
  • 함수는 작고 매우 자주 호출

하지 마십시오 :

  • 큰 기능 : 더 큰 실행 파일로 이어 지므로 호출 오버 헤드로 인한 빠른 실행에 관계없이 성능이 크게 저하됩니다.
  • I / O 바인딩 된 인라인 함수
  • 이 기능은 거의 사용되지 않습니다
  • 생성자와 소멸자 : 비어 있어도 컴파일러는 코드를 생성합니다
  • 라이브러리 개발시 바이너리 호환성 깨기 :
    • 기존 함수를 인라인
    • 인라인 함수를 변경하거나 인라인 함수를 비 인라인으로 만들기 : 라이브러리의 이전 버전은 이전 구현을 호출합니다.

라이브러리를 개발할 때 미래에 클래스를 확장 가능하게하려면 다음을 수행해야합니다.

  • 본문이 비어 있어도 인라인이 아닌 가상 소멸자를 추가
  • 모든 생성자를 비 인라인으로 만들기
  • 클래스를 값으로 복사 할 수없는 경우가 아니라면 복사 생성자와 할당 연산자의 비 인라인 구현을 작성하십시오.

inline키워드는 컴파일러에 대한 힌트 임을 기억하십시오 . 컴파일러는 함수를 인라인하지 않기로 결정할 수 inline있으며 처음 에는 표시되지 않은 함수를 인라인하기로 결정할 수 있습니다 . 나는 일반적으로 기능을 표시하지 않습니다 inline(아마도 매우 작은 기능을 작성할 때).

성능과 관련하여 현명한 접근 방식은 항상 응용 프로그램을 프로파일 링 한 다음 inline병목 현상을 나타내는 일련의 기능입니다.

참고 문헌 :


편집 : Bjarne Stroustrup, C ++ 프로그래밍 언어 :

함수는로 정의 될 수 있습니다 inline. 예를 들면 다음과 같습니다.

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

inline지정은의 호출 코드를 생성하려고 시도한다는 것을 컴파일러에 대한 힌트 fac()번 기능에 대한 코드를 내려 놓고 다음 일반적인 함수 호출 메커니즘을 통해 호출하는 것보다 인라인이 아니라. 영리한 컴파일러는 720호출에 대한 상수 생성 할 수 있습니다 fac(6). 상호 재귀적인 인라인 함수, 입력에 따라 반복되는 인라인 함수 등의 가능성으로 인해 inline함수 의 모든 호출 이 실제로 인라인 되는 것을 보장 할 수 없습니다 . 컴파일러의 영리한 정도는 법제화 될 수 없으므로 한 컴파일러는 720또 다른 컴파일러는 또 다른 컴파일러는 6 * fac(5)인라인되지 않은 호출을 생성 할 수 있습니다 fac(6).

비정상적으로 영리한 컴파일 및 연결 기능이없는 상태에서 인라인을 가능하게하려면 인라인 함수의 정의뿐만 아니라 정의도 범위 내에 있어야합니다 (§9.2). inlineespecifier은 함수의 의미에 영향을주지 않습니다. 특히, 인라인 함수에는 여전히 고유 한 주소가 있으므로 static인라인 함수의 변수 (§7.1.2)가 있습니다.

EDIT2 : ISO-IEC 14882-1998, 7.1.2 기능 지정자

지정자가있는 함수 선언 (8.3.5, 9.3, 11.4) inline은 인라인 함수를 선언합니다. 인라인 지정자는 호출 시점에서 함수 본문의 인라인 대체가 일반적인 함수 호출 메커니즘보다 선호됨을 구현에 표시합니다. 호출 시점에서이 인라인 대체를 수행하기 위해 구현이 필요하지 않습니다. 그러나이 인라인 대체가 생략 되더라도 7.1.2에 의해 정의 된 인라인 함수에 대한 다른 규칙은 여전히 ​​준수되어야합니다.


inline최적화와 관련이 거의 없습니다. inline주어진 정의 된 함수가 프로그램에서 여러 번 발생하는 경우 오류가 발생하지 않도록 컴파일러에 지시하는 명령이며, 사용되는 모든 번역에서 정의가 발생하고 모든 곳에서 정의가 정확히 동일한 정의를 가질 것이라고 약속합니다.

위의 규칙이 주어지면 inline선언에 필요한 것에 대한 추가 종속성을 포함하여 본문이 필요하지 않은 짧은 함수에 적합합니다. 정의가 발생할 때마다 구문 분석되어야하고 본문에 대한 코드가 생성 될 수 있으므로 단일 소스 파일에서 한 번만 정의 된 함수에 대한 일부 컴파일러 오버 헤드를 의미합니다.

컴파일러는 선택한 함수 호출을 인라인 (즉, 함수 호출을 해당 함수의 해당 동작을 수행하는 코드로 대체) 할 수 있습니다. 예전에는 호출과 동일한 변환 단위로 선언되지 않은 함수를 "명확하게"인라인 할 수 없었지만 링크 시간 최적화 사용이 증가함에 따라 지금도 사실이 아닙니다. 마킹 된 함수 inline가 인라인되지 않을 수도 있다는 사실도 마찬가지입니다 .


컴파일러에게 함수를 인라인하도록하는 것은 최적화이며, 최적화의 가장 중요한 규칙은 조기 최적화가 모든 악의 근원이라는 것입니다. 효율적인 알고리즘을 사용하여 항상 명확한 코드를 작성한 다음 프로그램을 프로파일 링하고 너무 오래 걸리는 기능 만 최적화하십시오.

If you find a particular function is very short and simple, and it's getting called tens of thousands of times in a tight inner loop, it might be a good candidate.

You might be surprised, though - many C++ compilers will automatically inline small functions for you - and they might ignore your request to inline, too.


The best way to find out is to profile your program and mark small functions that get called lots of times and burn through CPU cycles that as inline. The keyword here is "small" - once the function call overhead is negligible compared to the time spent in the function, it's pointless to inline them.

The other use I'd suggest is if you've got small functions that get called in performance critical code often enough to make a cache miss relevant, you should probably inline those as well. Again, it's something the profiler should be able to tell you.


Premature optimization is the root of all evil!

As a rule of thumb I usually inline only "getters" and "setters". Once the code is working and is stable, profiling can show which functions could benefit from inlining.

On the other hand, most modern compilers have quite good optimization algorithms, and will inline what you should have inlined for you.

Reasuming -- write inline one-liner functions, and worry about others later.


Inline functions might improve your code performance by eliminating the need to push arguments into the stack. if the function in question is in a critical part of your code you should make the inline not inline decision in the optimization part of your project,

you can read more about inlines in the c++ faq


I often use inline functions not as an optimization but to make the code more readable. Sometimes the code itself is shorter and easier to understand than comments, descriptive names etc. For example:

void IncreaseCount() { freeInstancesCnt++; }

The reader immediately knows the complete semantics of the code.


I generally follow a thumb rule where I make a function with 3-4 simple statements as inline. But it is good to remember that it is just a hint to the compiler. The final call to make it inline or not is taken by the compiler only. If there are more than these many statements I will not declare inline as with a stupid compiler it may lead to code bloat.


The best way would be to examine and compare the generated instructions for inlined and not inlined. However, it is always safe to omit inline. Using inline could lead to trouble you don't want.


When deciding on whether to use inline, I usually keep the following idea in mind: On modern machines memory latency can be a bigger bottleneck than raw calculations. Inlining functions that are called often is known to grow the executable size. Furthermore, such a function could be stored in the CPU's code cache which will decrease the number of cache misses when that code needs to be accessed.

Hence, you have to decide for yourself: Does inlining increase or decrease the size of the generated machine code? How likely is it that calling the function will cause a cache miss? If it is peppered throughout the code, then I would say the likelihood is high. If it is restricted to a single tight loop then the likelihood is hopefully low.

I typically use inlining in the cases I list bellow. However, where you are genuinely concerned about performance, profiling is essential. Furthermore, you might want to check whether the compiler actually takes the hint.

  • Short routines that are called in a tight loop.
  • Very basic accessors (get / set) and wrapper functions.
  • Template code in header files unfortunately automatically obtain the inline hint.
  • Short code that is used like a macro. (E.g. min() / max())
  • Short math routines.

Also, an inline method has severe side effects when maintaining large projects. When the inline code is changed, all files that use it will be rebuild automatically by the compiler (it it is a good compiler). This could waste a lot of your development time.

When an inline method is transferred to a source file and not inlined any more, the whole project must be rebuilt (at least this has been my experience). And also when methods are converted to inline.


One should use the inline function qualifier only when the function code is small.If the functions are larger you should prefer the normal functions since the saving in memory space is worth the comparatively small sacrifice in execution speed.


When you think your code is small enough to be used as inline and remember inline function duplicate your code and paste it were the function is called so it may be good enough to increase your execution time but increased memory consumption also. You can't use inline function when you are using a loop/static variable/recursive/switch/goto/Virtual function. Virtual means wait until runtime and inline means during compilation so they can't be use simultaneously.


I have read some answers and see that there some stuff missing.

The rule I use is not to use inline, unless I want it to be inline. Looks silly, now explanation.

Compilers are smart enough and short functions always makes inline. And never makes long function as inline, unless programmer said to do that.

I know that inline is a hint or request to compiler

Actually inline is an order for compiler, it has no choices and after inline keyword makes all code inline. So you can never use inline keyword and compiler will design shortest code.

So when to use inline?

To use if you want to have some code inline. I know only one example, because I use it in only one situation. It is user authentication.

For example I have this function:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

No matter how big this function is I want to have it as inline because it makes my software harder to crack.

참고URL : https://stackoverflow.com/questions/1932311/when-to-use-inline-function-and-when-not-to-use-it

반응형