2012-04-17 5 views
2

변경하지 않고 항상 0 인 함수 A, 함수 F, 함수 G 및 함수 H가있는 최신 인텔 데스크탑 프로세서에서 다음 코드를 호출하면 GCC 최신 버전의 -O3 최적화 :C++ 성능을 설명 할 수 없음

for(i = 0; i < a_big_number; i++) 
{ 
if(A != 0) F(); 
else G(); 
} 

실행에 2 초가 걸립니다. A는 항상 0이기 때문에 F는 절대로 호출되지 않습니다. 또는

for(i = 0; i < a_big_number; i++) 
{ 
if(A != 0) H(); 
else G(); 
} 

은 실행에 1 초 밖에 걸리지 않습니다. 다시 A는 항상 0이고 H는 절대로 호출되지 않습니다. 마지막으로

for(i = 0; i < a_big_number; i++) 
{ 
G(); 
} 

은 실행하는 데 0.5 초 밖에 걸리지 않습니다.

처음 두 예제의 조건문이 주어지면 F와 H의 내용이 중요한 이유는 무엇입니까? 그들은 결코 전화를받지 않았기 때문에 왜 그들이하는 일에 변화를 가져 왔을까요? 인텔 프로세서가 정교한 분기 예측을한다고 가정하면 프로세서는 G()가 항상 호출되고 조건문에서 시간을 낭비하지 않는다고 판단해서는 안됩니까? 조건부 학습은 시간을 낭비해야한다는 것을 이해하지만, 왜 그렇게 많은 시간을 낭비하는지 알지 못합니다. 이에

for(i = 0; i < a_big_number; i++) 
{ 
    if(A != 0) F(); 
    else G(); 
} 

:

+14

상대적인 성능을 나타내는 완벽하고 단순하며 컴파일 가능한 독립 실행 형 예제를 제공하십시오. 또한 몇 초 내에 실행되는 벤치 마크는 매우 시끄러운 결과를 초래할 가능성이 매우 높으며 성능 차이의 원인을 파악하는 가장 좋은 방법은 종종 생성 된 어셈블리를 보는 것입니다.) –

+0

왜 비교 명령문이 제로 시간이 걸릴까요? GCC가 그것을 최적화하기에 충분한 정보를 가지고 있지 않다면, CPU주기가 진행됩니다. – dasblinkenlight

+2

F, G 또는 H 중 하나가'inline'으로 선언 되었습니까? A가'const'로 선언 되었습니까?이 세 코드 조각은 하나의'main'에 나타 납니까? 후자에 관해서는 캐싱이 일부 성능 차이를 설명 할 수 있습니다. 3 개의 코드 블록을 재정렬하십시오. –

답변

1

그 컴파일러는 A는 상수 것을 이해 가정하면,이 코드를 설정해야

if(A != 0) 
    for(i = 0; i < a_big_number; ++i) 
     F(); 
else 
    for(i = 0; i < a_big_number; ++i) 
     G(); 

또는 완전히 F() 함수 호출을 최적화 일정한 나타납니다가있는 경우 컴파일 타임 상수.

부작용이 있거나 다른 방법이있을 수 있습니다 (컴파일러가 최적화 방법과 방법을 보장하지는 않음). 루프는 분기 오판 예측으로 인한 성능 저하가 발생합니다. CPU가 루프를 잠그고 A가 변경되지 않고 호출 된 함수가 충분히 작 으면 분기를 기억해야하므로 반복해서 동일한 실수를 반복하지 않습니다. 반면에 루프는 풀릴 수 있으며, 병렬화 될 수 없으며 코드 크기와 CPU가 추적해야하는 여러 가지 요소 만 불어 넣어서 많은 상처를 줄 수 있습니다.

나를 위해 미스테리 일뿐만 아니라 루프에서 호출하는 함수가 수행중인 작업 시간을 측정하는 방법. 예를 들어 프로세스 실행 스왑 아웃을 측정 할 수 있습니다. 따라서 측정 방법에 대한 자세한 설명이 포함 된 완전한 작동 예제를 제공하지 않는 한 계속 진행중인 상황을 알려주는 것은 불가능합니다.

어쨌든 시간 측정이 잘못되었거나 표시되지 않은 코드에서 위와 같은 결과가 나올 것입니다.

+2

+1 실제로 시간을 측정하는 데 귀하의 요점. 유감스럽게도 원하는 것을 실제로 측정하지 않는 방식으로 시간을 측정하는 것은 쉽습니다. 그리고 더 불행히도, 이것을 많이하지 않은 사람들은 시간 측정 방법이 문제가 될 수 없다고 철저히 확신하는 경향이 있습니다. : – Hurkyl

0

필자는 컴파일러가 분기가 실행되지 않을지 결정할 수 없다는 것을 알고있다. 컴파일러가 수행 할 수있는 최선의 방법은 어떤 분기가 더 많은지 예측하는 것입니다.

+0

컴파일러는 할 수 없지만 CPU는 잘 작동하는 분기 예측 메커니즘을 가지고 있습니다. 컴파일러가 실제로 생성 된 코드를 재 배열하기위한 분기 예측을위한 프로파일 기반 최적화 및 힌트를 가지고 있음은 말할 필요가 없습니다. –

관련 문제