2013-03-26 2 views
1
for (n = 0; n < L_SUBFR; n++) 
{ 
    s = 0; 
    for (i = 0; i <= n; i++) 
    { 
     s += exc[i] * h1[n - i]; 
    } 
    y1[n] = s; 
} 

Optimzed 버전 :은 루프 중첩 최적화

for (n = L_SUBFR; n != 0; n--) 
{ 
    for (i = n; i != 0; i--) 
    { 
     y1[n] = y1[n] + exc[i] * h1[n - i]; 
    } 
} 

내가 그러나 gcc 4.4.6.와 컴파일 후 AMD opteron 6274 비트 시스템에서 코드를 모두 실행 한, 내가 속도 또는 실행 시간에 어떤 이득을 볼 수 아니다 .

(1) 위의 코드를 더 이상 최적화 할 수있는 방법이 있습니까?

(2) 왜 내가 이득을 볼 수 없는지 말해 줄 수 있습니까?

+4

왜 두 번째 버전이 더 빠릅니까? 게다가, 그들은 동등한 기능을 가지고 있지 않다. – SomeWittyUsername

+1

** 컴파일러에 그런 최적화를 맡긴다. (두 버전이 같은 것을하고 있다고 가정 할 때 이는 의심 스럽다.) 컴파일러는 당신과 나보다 훨씬 더 좋다. –

+0

내부 루프에 저장할 수있는 사이클은'y1' 할당 문에서 소비 된 사이클에 완전히 휩싸입니다. 그런 다음 외부 루프에서 절약 할 수있는 사이클이 내부 루프에 의해 완전히 저지됩니다. –

답변

2

"빠른"코드가 아닌 읽을 수있는 코드를 만드는 데 집중해야합니다.

순 정렬을 빠른 정렬로 바꾸면 성능이 향상되고 (i != 0)(i)으로 바꾸는 대신 성능을 향상시킬 수 있습니다.

컴파일러가 모든 작업을 수행합니다.


가 목록에 업데이트 된 질문을 인용 요약하자면 있습니다 :

(1) 내가 더 위의 코드를 최적화 할 수있는 방법이 있나요?

물론, 당신은 (i)(n)(i != 0)(n != 0)를 교체하고 조금 빠르게 만들기 위해 코드 헛소리하고 하찮은 일에 속 태우고 모든 종류의 작업을 수행하지만, 결국, 당신은 정말 아무것도 변화되지 않을 수 있습니다 왜냐하면 컴파일러가 더 많은 최적화를하기 때문입니다. 종종 직접 생성 된 어셈블리를 최적화 할 수 있습니다.

(2) 왜 내가 이득을 볼 수 없는지 말해 줄 수 있습니까?

컴파일러 내 친구. 컴파일러가 여기에 아무 것도하지 않았더라도 나노 초 정밀 타이머가 없다면 이득을 얻지 못할 것입니다. 궁극적으로 귀하의 정의에 따라 달라집니다 L_SUBFR. 그냥 재미로에 대한


가 여기에 컴파일러가 무엇을 할 수 있는지의 예 :

unsigned int i = getValue(); 

if (i >= 10 && i <= 200) { 

} 

때문에 돌이킬 수없는, 그래서 최소한의 것 즉, 코드, 여기에 컴파일러에 의해 최적화 할 수 있습니다 :

unsigned int i = getValue(); 

if (i - 10 <= 190) { 

} 
+0

그냥 nitpicking : 컴파일러는 어셈블러를 최적화하지 않습니다, 일부 내부 표현을 최적화합니다 (예 : 버전 4.8이 릴리스 된 GCC 용 * Gimple *) ... 그리고 변환 된 내부 표현은 나중에 어셈블러로 변형됩니다 (일부를 통해 GCC의 RTL과 같은 다른 표현) –

+0

더 실현 가능성이 높습니다. 어셈블리 코드에 대한 최적화 프로그램을 직접 작성하려면 프로그래머에게 얼마를 지불해야합니까? : D –

+0

@ Magtheridon96 Plan 9에는 하나가 있습니다. Plan 9에서 오브젝트 파일은 일종의 "바이너리 어셈블러"일뿐입니다. 링커는 명령 선택과 같은 일종의 어셈블리 최적화를 수행합니다. – fuz