2011-02-10 1 views
2

우리는 이렇게 가고 공통 유틸리티 라이브러리에 오류 신호에 대한 매크로를 가지고 : 내가 parametersListHere으로 참조 각에서 컴파일러에 의해 채워집니다 상수와 매크로의 쉼표로 구분 된 목록입니다컴파일러가 함수를 인라인할지 여부를 결정하는 데 사용하는 실제 규칙 집합은 무엇입니까?

#define OurMacro(condition) \ 
    if(condition) { \ 
    } else { \ 
     CallExternalFunctionThatWillThrowAnException(parametersListHere); \ 
    } \ 

매크로 확장.

그 함수 호출은 항상 호출로 해석됩니다. 함수 구현은 컴파일러에 노출되지 않습니다. 이 함수에는 여섯 개의 매개 변수가 있고 디버그 구성에는 모두 의미있는 값을 가지며 릴리스 구성에서는 두 개만 의미있는 값을 갖고 나머지는 동일한 기본값을 전달합니다.

일반적으로 조건이 true로 유지되므로 호출 속도가 얼마나 빠르든지 신경 쓰지 않고 코드 확장에만 신경을 썼습니다. 6 개의 매개 변수로 해당 함수를 호출 할 때는 7 개의 x86 명령어 (6 push es와 하나의 call)가 필요하며 함수 서명이 두 개의 매개 변수만으로 변경된 경우에는 그 중 4 개를 피할 수 있습니다.이 작업은 중간 " 게이트 (gate) "함수는 구현 방식이 컴파일러에게 보이지 않는 방식으로 구현됩니다.

내가 그 변화를 주장해야 하는지를 추정해야합니다. 지금까지의 기본 개선점은 매개 변수의 수를 줄이면 각 인보 케이션에 4 개의 명령어가 삭제된다는 것입니다. 즉, 매크로 확장을 둘러싼 코드가 작아지고 컴파일러가 인라인 될 가능성이 높아지고 방출 된 코드를 더욱 최적화 할 수 있습니다.

코드를 실제로 시도하고 다시 컴파일하지 않고 코드를 신중하게 분석하지 않고 어떻게 계산할 수 있습니까? inline에 대해 읽을 때마다 컴파일러가 함수를 인라인할지 여부를 결정하는 설명이 있습니다.

함수 내부가 인라인 할 때 컴파일러 결정에 어떤 영향을 주는지에 대한 정확한 규칙 집합을 볼 수 있습니까?

+0

'#ifdef NDEBUG'스위치와 함께 2 개의 다른 기능이없는 이유가 무엇입니까? –

+0

@Matthieu M .: 원래 기능은 내가 모르는 코드에서 이미 호출되었을 수 있습니다. 어쨌든 새로운 함수가 있거나 기존 함수의 시그니처를 변경하면 똑같은 결과를 얻을 수 있으므로 어떤 방식으로 선택하든 상관 없습니다. – sharptooth

답변

3

GCC는 프로세스가 작동하는 방식을 공개하는 상당히 큰 옵션 집합을 가지고 있습니다 (here). 시간이 지남에 따라 조정될 것이고 CPU 의존적이기 때문에 정확한 것은 아닙니다.

첫 번째 규칙은 "해당 본문이 예상되는 함수 호출 코드보다 작습니다"입니다. 두 번째 규칙은 "한 번 호출되는 정적 함수"입니다.

인 링 프로세스에 영향을주는 매개 변수도 있습니다. max-inline-insns-single. insn은 GCC 컴파일러의 의사 명령어이며 여기서 함수 복잡성의 척도로 사용됩니다. 매개 변수 max-inline-insns-auto의 설명서를 보면 자동 인라이닝에 너무 커서 수동으로 함수 inline을 선언하면 인라이닝이 고려 될 수 있습니다.

-fpartial-inlining 플래그가 있기 때문에 인라인은 전부 또는 일부 처리가 아닙니다.

물론 인라이닝을 개별적으로 고려할 수는 없습니다. Common Subexpression Elimination (CSE)은 코드를 더 간단하게 만듭니다. 함수를 인라인 할 수있을만큼 작게 만들 수있는 최적화 과정입니다. 인라이닝 후에는 새로운 공통 하위 표현식이 발견 될 수 있으므로 CSE 패스를 다시 실행해야합니다. 그러면 차례로 인라인을 트리거 할 수 있습니다. 그리고 재방송이 필요한 유일한 최적화는 CSE가 아닙니다.

1

어떤 기능이 인라인되고 어떤 조건 (예 :선택한 최적화 수준)은 각 컴파일러마다 다르므로 컴파일러의 설명서를 확인하는 것이 좋습니다. 그러나 다른 함수로 전달하는 함수 (제안한대로)는이를 지원하는 모든 컴파일러에서 인라이닝 할 수있는 좋은 후보가되어야합니다.

일부 컴파일러에는 실제로 함수가 인라인되기를 원하는 플래그를 지정할 수있는 메커니즘이 있습니다. MSVC++에는 __forceinline이 있습니다.

+0

포워딩 기능을 인라이닝의 후보로 제안하지 않았습니다. 나는 그것을 인라인되지 않고 코드를 호출하는 코드가 더 작아 지도록이 코드가 consealed되기를 원한다. – sharptooth

+0

죄송합니다. 게이트 기능을 사용하기 위해 무엇을했는지 오해했습니다. 그 목적은 릴리스 모드에서 2 매개 변수 함수에 6 매개 변수 호출을 전달하여 찾고있는 결과를 얻는 것이라고 생각했습니다. (예 : 릴리스 빌드에서 추가 4 매개 변수에 대한 코드를 제거합니다. 게이트 함수 인라인 됨). – dc42

+0

게이트가 인라인되면 추가 매개 변수 전달이 인라인되고 여분의 코드가 다시 생성됩니다. – sharptooth

1

Visual C++를 사용하는 경우 __forceinline에서 까지을 사용하여 함수를 인라인 할 수 있습니다.