, 단지 컴파일러에 그를 둡니다. 나는 "미친"-O3
레벨에서 gcc가 출력하는 코드를 보았고 이러한 최적화 엔진을 작성한 사람들은 외계인이거나 실질적으로 먼 미래의 시간이라는 사실을 입증했습니다.
register
또는 inline
이 내 코드의 성능에서 상당한 차이를 보인 상황을 아직 보지 못했습니다. 그것이 을 의미하지는 않습니다. 컴파일러 작성자는 프로세서에서 마지막으로 온스의 성능을 추출 할 때 단순한 필사자보다 훨씬 더 많은 트릭을 알고 있습니다.
최적화가 진행되는 한 실제 문제가있는 경우에만 수행해야합니다. 이는 코드를 프로파일 링하고 병목 현상을 발견하는 것입니다.하지만 더 중요한 것은 컨텍스트가 느린 것으로 간주되지 않는 작업을 최적화하지 않는다는 것입니다. 원샷 작업이 10 분의 1 초 또는 100 분의 1이 걸릴지 여부는 사용자와의 차이가 없습니다.
그리고 때때로는 가독성을위한 최적화는 당신이 옆으로
:-)이 gcc가 당신을 위해 수행하는 멋진 트릭 단지 하나이다 할 수있는 최선의 하나입니다. 맞아
main: pushl %ebp ; stack frame setup.
movl $720, %eax ; just load 720 (6!) into eax.
movl %esp, %ebp ; stack frame
popl %ebp ; tear-down.
ret ; and return.
는, GCC 그냥 컴파일 시간에 그것을 모두 밖으로 작동합니다
static int fact (unsigned int n) {
if (n == 0) return 1;
return n * fact (n-1);
}
int main (void) {
return fact (6);
}
이 (-O3
에서)로 컴파일 : 그것을 계승을 계산하고 반환하도록되어 다음과 같은 코드를 살펴 보자 -O0
(순진) 버전
int main (void) { return 720; }
명암이 :와 동등한로 전체를 회전
main: pushl %ebp ; stack
movl %esp, %ebp ; frame
andl $-16, %esp ; set
subl $16, %esp ; up.
movl $6, (%esp) ; pass 6 as parameter.
call fact ; call factorial function.
leave ; stack frame tear down.
ret ; and exit.
fact: pushl %ebp ; stack
movl %esp, %ebp ; frame
subl $24, %esp ; set up.
cmpl $0, 8(%ebp) ; passed param zero?
jne .L2 ; no, keep going.
movl $1, %eax ; yes, set return to 1.
jmp .L3 ; goto return bit.
.L2: movl 8(%ebp), %eax ; get parameter.
subl $1, %eax ; decrement.
movl %eax, (%esp) ; pass that value to next level down.
call fact ; call factorial function.
imull 8(%ebp), %eax ; multiply return value by passed param.
.L3: leave ; stack frame tear down.
ret ; and exit.
컴파일러도 사람들입니다! :-) 코드가 읽기 쉽고 이해하기 쉬운 경우, 사용자의 의도를보고 코드를 생성합니다. 이전에 보지 못했던 "똑똑한 트릭"을한다면, 당신의 동료들도 컴파일러도 그걸로 무엇을해야하는지 알지 못할 것입니다. –