프레임 포인터는 언제 생략해야 합니까?
프레임 포인터를 생략할 때 실질적인 최적화가 있습니까?내가 이 페이지를 읽어서 제대로 이해했다면,-fomit-frame-pointer
프레임 포인터의 저장, 설정 및 복원을 피하고 싶을 때 사용됩니다.
이 작업은 각 기능 호출에 대해서만 수행되는 작업이며, 그렇다면 각 기능에 대해 몇 가지 지침을 피할 가치가 있습니까?최적화를 위해서는 사소한 것이 아닙니까?디버깅 제한과 별개로 이 옵션을 사용할 경우의 실제 의미는 무엇입니까?
이 옵션을 사용하거나 사용하지 않고 다음 C 코드를 컴파일했습니다.
int main(void)
{
int i;
i = myf(1, 2);
}
int myf(int a, int b)
{
return a + b;
}
,
# gcc -S -fomit-frame-pointer code.c -o withoutfp.s
# gcc -S code.c -o withfp.s
.
diff -u
두 파일에서 다음과 같은 조립 코드가 밝혀졌습니다.
--- withfp.s 2009-12-22 00:03:59.000000000 +0000
+++ withoutfp.s 2009-12-22 00:04:17.000000000 +0000
@@ -7,17 +7,14 @@
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
- pushl %ebp
- movl %esp, %ebp
pushl %ecx
- subl $36, %esp
+ subl $24, %esp
movl $2, 4(%esp)
movl $1, (%esp)
call myf
- movl %eax, -8(%ebp)
- addl $36, %esp
+ movl %eax, 20(%esp)
+ addl $24, %esp
popl %ecx
- popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
@@ -25,11 +22,8 @@
.globl myf
.type myf, @function
myf:
- pushl %ebp
- movl %esp, %ebp
- movl 12(%ebp), %eax
- addl 8(%ebp), %eax
- popl %ebp
+ movl 8(%esp), %eax
+ addl 4(%esp), %eax
ret
.size myf, .-myf
.ident "GCC: (GNU) 4.2.1 20070719
누가 위 코드에서 -fomit-frame-pointer가 실제로 차이를 만든 핵심 사항을 설명해 주실 수 있습니까?
편집: objdump
의 출력을 로 대체했습니다.gcc -S
의
-fomit-frame-pointer
는 일반 용도로 사용할 수 있는 레지스터를 하나 더 허용합니다.레지스터가 좀 부족한 32비트 x86에서는 정말 대단한 일이라고 생각합니다.*
모든 함수 호출에서 EBP가 더 이상 저장 및 조정되지 않고, 일반 코드에서 EBP를 추가로 사용할 수 있으며, EBP가 범용 레지스터로 사용되는 경우 스택 작업이 더 적을 것으로 예상됩니다.
코드가 너무 간단해서 이런 최적화의 이점을 전혀 볼 수 없습니다. 레지스터를 충분히 사용하지 않는 것입니다.또한 이러한 효과를 확인하는 데 필요할 수 있는 최적화 도구를 아직 설정하지 않았습니다.
* 마이크로아키텍처 레지스터가 아닌 ISA 레지스터.
생략의 유일한 단점은 디버깅이 훨씬 더 어렵다는 것입니다.
가장 큰 장점은 성능에 큰 차이를 가져올 수 있는 하나의 추가 범용 레지스터가 있다는 것입니다.분명히 이 여분의 레지스터는 필요할 때만 사용됩니다(아마도 매우 단순한 기능에서는 그렇지 않을 것입니다). 일부 기능에서는 다른 기능보다 더 많은 차이가 있습니다.
당신은 종종 GCC로부터 더 의미있는 조립 코드를 얻을 수 있습니다.-S
어셈블리를 출력하기 위한 인수:
$ gcc code.c -S -o withfp.s
$ gcc code.c -S -o withoutfp.s -fomit-frame-pointer
$ diff -u withfp.s withoutfp.s
GCC는 주소를 신경쓰지 않기 때문에 실제 생성된 명령어를 직접 비교할 수 있습니다.리프 기능의 경우 다음을 제공합니다.
myf:
- pushl %ebp
- movl %esp, %ebp
- movl 12(%ebp), %eax
- addl 8(%ebp), %eax
- popl %ebp
+ movl 8(%esp), %eax
+ addl 4(%esp), %eax
ret
GCC는 프레임 포인터를 스택에 푸시하기 위한 코드를 생성하지 않으며, 이것은 스택의 함수에 전달되는 인수의 상대 주소를 변경합니다.
프로그램을 프로파일링하여 유의한 차이가 있는지 확인합니다.
다음으로 개발 프로세스를 프로파일링합니다.디버깅이 더 쉽습니까, 더 어렵습니까?개발에 더 많은 시간을 쓰십니까, 아니면 더 적은 시간을 쓰십니까?
프로파일링 없이 최적화하는 것은 시간과 비용의 낭비입니다.
언급URL : https://stackoverflow.com/questions/1942801/when-should-i-omit-the-frame-pointer
'programing' 카테고리의 다른 글
불법 논변예외: 탐색 대상 xxxx는 이 NavController에 알 수 없습니다. (0) | 2023.10.29 |
---|---|
XML과 XSD의 차이점은 무엇입니까? (0) | 2023.10.29 |
장고에서 jQuery/Ajax와 함께 포스팅하려면 어떻게 해야 합니까? (0) | 2023.10.29 |
기토시스 대 기토라이트? (0) | 2023.10.29 |
AngularJS에서 쿼리 문자열 제거 (0) | 2023.10.24 |