예를 제안합니다. 조건 계산을 검사하는 데 ~ 60 사이클이 소요되며 컴파일러 자체에서 컴파일 시간에 계산할 수 없습니다.방법 GCC 컴파일러에게 더 많은 가능성이 지점
if (__builtin_expect(almost_always_false_condition,0)) {
// do something
}
그러나 :
(GCC 4.3)
예를 제안합니다. 조건 계산을 검사하는 데 ~ 60 사이클이 소요되며 컴파일러 자체에서 컴파일 시간에 계산할 수 없습니다.방법 GCC 컴파일러에게 더 많은 가능성이 지점
if (__builtin_expect(almost_always_false_condition,0)) {
// do something
}
그러나 :
(GCC 4.3)
당신이 조건이 코드의 흐름을 정리하기위한 힌트로 주어진 값을 가질 가능성이 있다는 GCC에 제안하고 싶은 경우에, 당신은 __builtin_expect()
를 사용해야합니다 __builtin_expect()
이 수행하지 않을 상태를 피하는 방법을 찾고 싶다는 생각이들 것입니다.
if (__builtin_expect(fastCheckThatIsTrueIfFullConditionIsTrue,0)) {
// most of the time, we don't even get to here, so you don't need
// to evaluate the condition
if (almostAlwaysFalseCondition) {
// do something
}
}
당신이 우리에게 조건이 무엇인지에 대한 자세한 내용을 말해 줄 수 : 신속 조건에 근접하고 근사치에 해당하는 경우에만 전체 검사를 할 수있는 방법이 있나요?
이 힌트와 예제를 보내 주셔서 감사합니다. 조건은 로깅에 사용되며 필요에 따라 전환 될 수 있습니다. 값은 컴파일 타임에 알려지지 않습니다 (우리는 로깅 및 로그 오프와 함께 두 가지 버전의 바이너리를 가질 수 없습니다). "빠른 검사"는 가능한 경우 이미 완료되었습니다. – Karol
__builltin_expect는 코드 플로우를 어떻게보다 효율적으로 변경합니까? 같은 확장자를 가지고 있지 않은 컴파일러에서이 작업을 수행 할 수있는 이식성있는 방법이 있습니까? – greatwolf
@ 빅터 T .: 아니오, 이것을 수행 할 수있는 휴대용 방법이 없습니다. –
설명서에 따르면 gcc는 프로필 기반 최적화를 수행합니다 (또는 수행 할 수 있음). gcc로 해본 적이 없으므로 더 이상의 조언을 드릴 수 없으며 Google을 치는 동안 가치가있을 것입니다.
단일 실행 중에 결과가 다를 수있는 경우 부울 연산자의 지연 평가를 사용하여 조건을 값싼 부분과 값 비싼 부분으로 나누고 저렴한 부분을 먼저 실행할 수 있습니다. a == 5
을 계산하기 때문에
if (a == 5 && somethingexpensive())
{
...
}
은 somethingexpensive()
보다 저렴하고, 거의 항상 false
경우에는 somethingexpensive
절을 평가하는 것을 피한다, 이는 먼저 실행해야합니다.
결과가 프로그램 실행에 대해 일정한 경우 정적 또는 전역 변수에 계산 결과를 저장하여 최적화 할 수 있습니다.
static int result = doevalfunctiononlyonce();
if (result)
{
....
}
이렇게하면 if
의 비용을 간단한 메모리 조회로 줄일 수 있습니다. 조건은 다른 프로 시저에서 작업에 대한 응답으로 변경하면
, 당신은 그 과정에서 전역을 업데이트 할 수 있습니다
int condition;
void appendToList(int a)
{
list.append(a);
if (list.somethingexpensive())
{
condition = true;
} else
{
condition = false;
}
}
void someotherfunction()
{
// if (list.somethingexpensive())
if (condition)
{
...
}
}
이 유용 someotherfunction
가 더 자주 appendtolist
기능보다 더 많이 불려 갔을 경우.
우선, else
절 또는 프로그램의 다른 곳에서 몇 사이클을 소비합니까? 당신이 프로파일을 작성하거나 stackshots을받는다면, 그 시험에 적어도 10 %의 시간을 소비하고 있습니까? 그렇지 않다면, 아마도 당신이 먼저보아야 할 더 큰 문제가있을 것입니다.
둘째, 테스트에서 10 %를 초과하여 소비한다면 알고리즘이 50-50 확률에 가까운 결정 포인트를 갖도록 조정할 수 있는지 확인해야합니다. 50-50 결정 지점은 실행될 때 1 비트의 정보를 산출하지만 99-1 결정 포인트는 약 .07 비트 * 만 산출합니다. 즉, CPU 사이클을 비효율적으로 사용합니다.)이 현상의 예는 선형 검색과 이진 검색을 비교하는 경우입니다.
* 이진 결정 포인트가 있고 결과의 확률이 a
및 b
인 경우 정보 산출량 (엔트로피)은 비트 수는 -(a*log(a) + b*log(b))/log(2)
입니다.
제 생각에는 이러한 종류의 최적화를 수행하는 가장 좋은 방법은 -fprofile-generate
및 -fprofile-use
옵션을 사용하는 것입니다. 이것은 무엇이 가능하고 그렇지 않은지에 대한 정보를 수집하기 위해 대표적인 유스 케이스의 기반을 필요로하지만, 이러한 목적으로 테스트가 사용될 수 있습니다. 다른면에서는 코드가 추악하고 휴대하기 어려운 지시문으로 장식되어 있지 않습니다.
이 두 옵션에 대한 자세한 내용은 https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Optimize-Options.html#Optimize-Options을 참조하십시오.
관련 : http://stackoverflow.com/questions/1668013/can-likely-unlikely-macros-be-used-in-user-space-code –