인라인은 컴파일러에 대한 힌트 또는 요청이며 함수 호출 오버 헤드를 피하는 데 사용됩니다.
따라서 함수가 인라인 후보인지 여부를 어떤 기준으로 결정할 수 있습니까? 어떤 경우에는 인라인을 피해야합니까?
인라인은 컴파일러에 대한 힌트 또는 요청이며 함수 호출 오버 헤드를 피하는 데 사용됩니다.
따라서 함수가 인라인 후보인지 여부를 어떤 기준으로 결정할 수 있습니까? 어떤 경우에는 인라인을 피해야합니까?
답변:
함수 호출 비용을 피하는 것은 이야기의 절반에 지나지 않습니다.
하다:
inline
대신에 사용#define
inline
더 빠른 코드와 더 작은 실행 파일에 적합합니다 (코드 캐시에 더 많은 기회가있을 수 있음)하지 마십시오 :
라이브러리를 개발할 때 미래에 클래스를 확장 가능하게하려면 다음을 수행해야합니다.
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).
inline
especifier은 함수의 의미에 영향을주지 않습니다. 특히 인라인 함수에는 여전히 고유 한 주소가 있으므로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
컴파일러가 그렇게 느끼면 비 기능을 인라인 할 수 있습니다. 그리고 inline
컴파일러가 인라인하지 않기로 결정하면 함수가 인라인되지 않습니다. Charles Bailey가 말했듯이 언어 규칙이 변경됩니다. 최적화 힌트로 생각하기보다는 완전히 다른 개념으로 생각하는 것이 더 정확합니다. inline
키워드는 여러 정의를 허용하는 컴파일러, 그리고 아무것도를 알려줍니다. "인라인"최적화는 표시 여부에 관계없이 거의 모든 기능에 적용 할 수 있습니다 inline
.
inline
함수 인라인을 얻기 위해 모든 것을 사용하는 것은 아닙니다 . 때때로 우리는 ODR을 이용하는 것과 같은 다른 혜택을 원합니다.
inline
최적화와 관련이 거의 없습니다. inline
주어진 정의 된 함수가 프로그램에서 여러 번 발생하는 경우 오류가 발생하지 않도록 컴파일러에 지시하는 명령이며, 사용되는 모든 번역에서 정의가 발생하고 모든 곳에서 정의가 정확히 동일한 정의를 가질 것이라고 약속합니다.
위의 규칙이 주어지면 inline
선언에 필요한 것에 대한 추가 종속성을 포함하여 본문이 필요하지 않은 짧은 함수에 적합합니다. 정의가 발생할 때마다 구문 분석되어야하고 본문에 대한 코드가 생성 될 수 있으므로 단일 소스 파일에서 한 번만 정의 된 함수에 대한 일부 컴파일러 오버 헤드를 의미합니다.
컴파일러는 선택한 함수 호출을 인라인 (즉, 함수 호출을 해당 함수의 해당 동작을 수행하는 코드로 대체) 할 수 있습니다. 예전에는 호출과 동일한 변환 단위로 선언되지 않은 함수를 "명확하게"인라인 할 수 없었지만 링크 시간 최적화 사용이 증가함에 따라 지금도 사실이 아닙니다. 마킹 된 함수 inline
가 인라인되지 않을 수도 있다는 사실도 마찬가지입니다 .
inline
키워드 와 연계는 어떤 관계가 있습니까? 그리고 행복한 우연의 일치는 무엇입니까?
컴파일러에게 함수를 인라인하도록하는 것은 최적화이며, 최적화의 가장 중요한 규칙은 조기 최적화가 모든 악의 근원이라는 것입니다. 효율적인 알고리즘을 사용하여 항상 명확한 코드를 작성한 다음 프로그램을 프로파일 링하고 너무 오래 걸리는 기능 만 최적화하십시오.
특정 함수가 매우 짧고 단순하다는 것을 알고 내부 꽉 조여진 루프에서 수만 번 호출되면 좋은 후보가 될 수 있습니다.
그러나 많은 C ++ 컴파일러가 자동으로 작은 함수를 인라인하고 인라인 요청을 무시할 수도 있습니다.
/FAcs
Visual Studio, -s
GCC) 와 함께 어셈블리 언어를 내보내도록 설정하여 정확히 무엇을하는지 확인할 수 있습니다. 내 경험상 두 컴파일러 모두 인라인 키워드의 무게를 상당히 weigh니다.
inline
키워드에 무게를 두지 않기 때문에 흥미 롭습니다 . 즉, 함수가 인라인되는 것을보고 inline
지정자를 제거 하면 여전히 인라인됩니다. 반대의 구체적인 예가 있다면 공유하십시오!
inline
키워드을 방해 "명확한 코드를?" "조기 최적화"의 키워드는 조기 하지 최적화. 적극적으로 최적화를 피해야한다고 말하는 것은 쓰레기 일뿐입니다. 그 말의 요점은 필요하지 않은 최적화를 피하고 코드에 유해한 부작용 (예 : 유지 관리가 덜하도록)을 피해야한다는 것입니다. 나는 방법을 보려면 실패 inline
키워드는 코드가 덜 유지 보수 만들려고, 또는 함수에 추가하는 해가 될 수있는 방법.
조기 최적화는 모든 악의 근원입니다!
경험상 일반적으로 "getters"와 "setters"만 인라인합니다. 코드가 작동하고 안정되면 프로파일 링은 어떤 함수가 인라인으로 혜택을 볼 수 있는지 보여줄 수 있습니다.
다른 한편으로, 대부분의 최신 컴파일러는 꽤 좋은 최적화 알고리즘을 가지고 있으며 인라인해야 할 내용을 인라인합니다.
재개-인라인 원 라이너 기능을 작성하고 나중에 다른 것에 대해 걱정하십시오.
인라인 사용 여부를 결정할 때는 일반적으로 다음과 같은 아이디어를 염두에 두어야합니다. 최신 머신에서는 메모리 대기 시간이 원시 계산보다 병목 현상이 클 수 있습니다. 종종 호출되는 인라인 함수는 실행 파일 크기를 늘리는 것으로 알려져 있습니다. 또한 이러한 기능을 CPU의 코드 캐시에 저장하면 해당 코드에 액세스해야 할 때 캐시 누락 수를 줄일 수 있습니다.
따라서 인라인은 생성 된 기계어 코드의 크기를 늘리거나 줄입니까? 함수를 호출하면 캐시 미스가 발생할 가능성은 얼마나됩니까? 코드 전체에 후추가 뿌려지면 가능성이 높다고 말할 것입니다. 단일 타이트 루프로 제한되면 가능성이 낮을 것입니다.
나는 일반적으로 다음과 같은 경우에 인라인을 사용합니다. 그러나 성능에 대해 정말로 우려하는 경우 프로파일 링이 필수적입니다. 또한 컴파일러가 실제로 힌트를 취하는 지 확인하고 싶을 수도 있습니다.
또한 인라인 방법은 대규모 프로젝트를 유지 관리 할 때 심각한 부작용이 있습니다. 인라인 코드가 변경되면 해당 코드를 사용하는 모든 파일이 컴파일러에 의해 자동으로 다시 작성됩니다 (좋은 컴파일러입니다). 개발 시간이 많이 소요될 수 있습니다.
때 inline
방법은 소스 파일로 전송하고 더 이상 인라인되지 않고, 전체 프로젝트는 (적어도이 내 경험이었다) 다시 작성해야합니다. 또한 메소드가 인라인으로 변환되는 경우.
inline
상관없이 ( 키워드가없는 경우 inline
제외) 링커 오류가 발생하지만 inline
키워드가 과도한 재 구축을 유발하는 문제는 아닙니다.
나는 몇 가지 답변을 읽었으며 누락 된 것들이 있음을 알았습니다.
내가 사용하는 규칙은 인라인이 아닌 한 인라인을 사용하지 않는 것입니다. 어리석은 표정 이네요.
컴파일러는 충분히 똑똑하고 짧은 기능은 항상 인라인을 만듭니다. 프로그래머가 그렇게 말하지 않는 한 긴 기능을 인라인으로 만들지 마십시오.
인라인이 힌트 또는 컴파일러 요청이라는 것을 알고 있습니다.
실제로 inline
컴파일러의 순서이며 선택의 여지가 없으며 after inline
키워드는 모든 코드를 인라인으로 만듭니다. 그래서 당신은 결코 사용할 수 없습니다inline
키워드를 컴파일러는 가장 짧은 코드를 설계합니다.
그래서 언제 사용 inline
합니까?
코드를 인라인으로 사용하려는 경우에 사용합니다. 한 가지 상황에서만 사용하기 때문에 한 가지 예만 알고 있습니다. 사용자 인증입니다.
예를 들어이 기능이 있습니다.
inline bool ValidUser(const std::string& username, const std::string& password)
{
//here it is quite long function
}
이 기능이 아무리 커도 소프트웨어를 크랙하기 어렵 기 때문에 인라인으로 만들고 싶습니다.
inline
무엇 C ++ 신인이다CFLAGS
젠투 신인에 있습니다 : 아니, 컴파일하는 것은-O3 -funroll-loops -finline-functions
기존의 펜티엄 비행하지 않습니다)