"거의"및 "거의"매크로의 사용량이 너무 많습니까?


12

로 알려진 매크로 likelyunlikely매크로를 사용하면 컴파일러에서 if일반적으로 입력 여부를 알 수 있습니다. 이를 사용하면 성능이 약간 향상됩니다.

최근에 사용하기 시작했으며 그러한 힌트를 얼마나 자주 사용해야하는지 잘 모르겠습니다. 현재 오류 검사와 함께 사용하며 if일반적으로로 표시됩니다 unlikely. 예를 들면 다음과 같습니다.

mem = malloc(size);
if (unlikely(mem == NULL))
  goto exit_no_mem;

괜찮아 보이지만 오류 검사는 if자주 발생하며 결과적으로 상기 매크로를 사용합니다.

내 질문은이 너무 많이입니다 likelyunlikely모든 오류 검사에 매크로 if?

우리가 그것에있는 동안, 그들은 어떤 다른 장소를 자주 사용합니까?


현재 사용중인 곳은 실시간 서브 시스템에서 추상화하는 라이브러리에 있으므로 RTAI, QNX 및 다른 사람들 사이에서 프로그램을 이식 할 수 있습니다. 즉, 대부분의 함수는 다소 작으며 하나 또는 두 개의 다른 함수를 직접 호출합니다. 많은 static inline기능 조차도 있습니다.

우선, 그것은 내가 프로파일 할 수있는 응용 프로그램이 아닙니다. 독립 실행 형 응용 프로그램이 아니라 라이브러리이기 때문에 "병목 현상"을 식별하는 것은 의미가 없습니다.

둘째, 그것은 "이것이 가능하지 않다는 것을 알고 있습니다. 컴파일러에게도 알려줄 것입니다." 적극적으로 최적화하려고하지 않습니다 if.


7
나에게 마이크로 최적화의 악취가 ...
래칫 괴물

2
응용 프로그램 코드의 경우 프로파일 링 에서이 코드가 핫 경로에서 사용되는 것으로 표시된 경우에만 추가합니다.
코드 InChaos


@ 제임스, 그건 그냥 말한다 likelyunlikely존재하고 그들이 무엇을 할. 언제 어디서 사용하는 것이 가장 좋은지 찾지 못했습니다.
Shahbaz

@Shahbaz "조건이 자주 거짓이면 실행이 선형이 아닙니다. 프리 페치로 인해 L1i를 오염시킬뿐만 아니라 중간에 사용되지 않는 코드 덩어리가 많으므로 분기 예측에 문제가 발생할 수 있습니다. 분기 예측이 잘못되었습니다. 조건식이 매우 비효율적 일 수 있습니다. " 따라서 필요한 지침이 L1i 캐시에 있는지 확인하려는 엄격한 루프
James

답변:


12

그 코드를 기꺼이 오염시키려는 성능이 필요합니까? 사소한 최적화입니다.

  • 코드가 타이트한 루프로 실행됩니까?
  • 응용 프로그램에 성능 문제가 있습니까?
  • 애플리케이션을 프로파일 링하고이 특정 루프가 많은 CPU 시간을 소비한다고 결정 했습니까?

yes위의 모든 것에 대답 할 수 없다면 , 이런 것들을 신경 쓰지 마십시오.

편집 : 편집에 대한 응답으로. 프로파일 링 할 수없는 경우에도 일반적으로 핫스팟을 추정 할 수 있습니다. 모든 사람이 호출하는 메모리 할당 함수는 특히 전체 라이브러리에 대해 매크로를 한 번만 사용해야하기 때문에 좋은 후보입니다.


1
분명히 말해서, 난 당신을 투표하지 않았다. 그러나 귀하의 답변이 실제로 내 질문에 대답하지는 않습니다. (un)likely매크로가 거의 사용되지 않고 성능이 매우 중요한 코드에서만 사용 된다고 말하고 있습니까? 자주 사용하는 것이 "나쁜 습관"입니까, 아니면 단지 "불필요한"것입니까?
Shahbaz

@Shahbaz 코드를 읽기 어렵게 만들고 성능 최적화는 사소한 게인에서 사소한 손실에 이르기까지 다양합니다. 후자의 가능성에 대한 가정이 나중에 코드의 다른 부분으로 변경되어 잘못되었거나 잘못 변경되었을 때. 필요한 경우가 아니면 절대 사용해서는 안됩니다.
Peter

3
@Peter : 구문이 너무 나쁘지는 않지만 코드를 읽는 사람 에게 유용한 정보를 제공 할 가능성이 있거나 없을 가능성에 대한 표기법 이 있습니다. 예를 들어,을 본 사람 if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }은 프로그래머가 if값 2 및 3에 대해 a를 사용하는 것이 C가 두 개의 case레이블을 단일 핸들러와 연관시킬 수 있다는 것을 알지 못한 결과가 아니라고 판단 할 수 있습니다 .
supercat

내가 느끼는 것이 중요하다고 언급 한 사람은 없습니다. "불확실한"경로는 덜 자주 발생하는 것이 아니라 속도에 전혀 신경 쓰지 않는 경로에 따라 조정될 수 있습니다 . 예를 들어, 주변 장치가 응답하지 않기 때문에 재설정하고 어쨌든 잠 자야합니다.
Benjamin Lindqvist

2

x86 / x64 용으로 작성 중이고 20 년 된 CPU를 사용하지 않는 경우 __builtin_expect ()를 사용하면 얻을 수있는 성능 이점은 무시할 수 있습니다. 그 이유는 최신 x86 / x64 CPU (Atom에 대해서는 100 % 확신 할 수 없음)가 동적 분기 예측을 갖기 때문에 기본적으로 CPU가 더 자주 수행되는 분기에 대해 "학습"합니다. 물론,이 정보는 제한된 수의 브랜치에 대해서만 저장 될 수 있지만 두 가지 경우 만 가능합니다. (a) "자주 사용하는"브랜치 인 경우 프로그램에서 해당 동적 브랜치 예측의 이점을 얻을 수 있으며 (b) "희귀 한"브랜치 인 경우 잘못된 예측으로 인해 실제 성능이 저하되지 않습니다. 그런 희귀 한 가지들 (지점 오해의 CPU주기는 20 회가 한 번 블루 문에서 발생하면 너무 나쁘지 않다).

NB : 이것은 현대 x86 / x64에서 분기 오 예측의 중요성이 낮아졌다는 것을 의미하지는 않습니다. 여전히 피해야합니다. x86 / x64에서 __builtin_expect ()의 중요성은 중요합니다 (IIRC, 약 10-15 년 전). 대부분 동적 분기 예측 때문입니다.

NB2 : x86 / x64 이외의 다른 플랫폼 인 YMMV


글쎄, 컴파일러는 CPU가 어느 브랜치를 덜 기대할 지 알고 있습니다. 그리고 그것은 실제로 가능성이 거의없는 것을 주선 할 수 있습니다. 그러나 컴파일러는 아마도 unlikely-notation 없이 해당 패턴을 알고있을 것입니다 .
중복 제거기

@ 중복 제거기 : 동적 분기 예측을 사용하면 컴파일러는 CPU가 코드 의이 시점을 통해 이전 실행을 기반으로 런타임에서 계산할 때 어느 분기가 더 가능성이 높은지 알지 못합니다.
No-Bugs Hare
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.