코드가 꼬리 호출 최적화를 적극적으로 방지하려는 이유는 무엇입니까?
질문의 제목이 약간 이상 할 수 있지만, 제가 아는 한 테일 콜 최적화에 반대하는 것은 전혀 없습니다. 그러나 오픈 소스 프로젝트를 탐색하는 동안 컴파일러가 테일 호출 최적화를 수행하는 것을 적극적으로 막으려는 몇 가지 기능 (예 : 이러한 해킹으로 가득 찬 CFRunLoopRef 구현)을 이미 발견했습니다 . 예를 들면 :
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
if (func) {
func(observer, activity, info);
}
getpid(); // thwart tail-call optimization
}
이것이 왜 그렇게 중요해 보이는지 알고 싶습니다. 일반 개발자로서이 점을 염두에 두어야하는 경우가 있습니까? 예 : 꼬리 호출 최적화에 일반적인 함정이 있습니까?
제 생각 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
에는 디버깅 목적으로 스택 추적에 있는지 확인하는 것 입니다. 그것은이 __attribute__((no inline))
이 아이디어를 백업한다.
아시다시피, 그 함수는 그냥 다른 함수로 바운스됩니다. 그래서 그것은 디버깅을 돕기 위해 그런 장황한 이름으로 만 생각할 수있는 트램폴린의 한 형태입니다. 이는 함수가 다른 곳에서 등록 된 함수 포인터를 호출하고 있으므로 해당 함수에 액세스 가능한 디버깅 기호가 없을 수 있다는 점을 고려할 때 특히 유용합니다.
유사한 작업을 수행하는 유사한 이름의 다른 함수도 주목하십시오. 역 추적에서 발생한 일을 확인하는 데 도움이되는 것 같습니다. 이것은 핵심 Mac OS X 코드이며 충돌 보고서 및 프로세스 샘플 보고서에도 표시됩니다.
이것은 추측 일 뿐이지 만 스택 오버플로 오류로 인해 무한 루프 대 폭격을 피할 수 있습니다.
문제의 메서드가 스택에 아무것도 넣지 않기 때문에 꼬리 호출 재귀 최적화가 반환 주소를 스택에 넣는 최적화되지 않은 코드와는 반대로 무한 루프에 들어가는 코드를 생성하는 것이 가능해 보일 것입니다. 오용시 결국 넘칠 것입니다.
내가 가진 유일한 생각은 디버깅 및 스택 추적 인쇄를 위해 스택에 대한 호출을 보존하는 것과 관련이 있습니다.
한 가지 잠재적 인 이유는 디버깅 및 프로파일 링을 더 쉽게 만드는 것입니다 (TCO를 사용하면 상위 스택 프레임이 사라지고 스택 추적을 이해하기가 더 어려워 짐).
'code' 카테고리의 다른 글
대용량 어레이 스토리지 (플랫 바이너리 파일 대신)에 HDF5를 사용하면 분석 속도 또는 메모리 사용 이점이 있습니까? (0) | 2020.10.10 |
---|---|
Django의 FileField를 기존 파일로 설정 (0) | 2020.10.10 |
Eclipse를 Indigo에서 Juno로 업그레이드하는 설정을 유지할 수 있습니까? (0) | 2020.10.10 |
자바 스크립트에서 'throw'후에 'return'이 필요합니까? (0) | 2020.10.10 |
string.Empty vs null. 어떤 것을 사용합니까? (0) | 2020.10.10 |