IT이야기

코드가 테일콜 최적화를 적극적으로 막으려고 하는 이유는 무엇입니까?

cyworld 2022. 6. 21. 23:06
반응형

코드가 테일콜 최적화를 적극적으로 막으려고 하는 이유는 무엇입니까?

질문의 제목은 조금 이상할 수 있지만, 제가 알기론 테일콜 최적화에 반대되는 것은 전혀 없습니다.그러나 오픈소스 프로젝트를 브라우징하던 중 컴파일러가 테일콜 최적화를 하지 못하도록 적극적으로 시도하는 몇 가지 함수를 발견했다.예를 들어, 그러한 해킹으로 가득 찬 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를 사용하면 부모 스택프레임이 사라지기 때문에 스택트레이스를 이해하기 어려워집니다).

언급URL : https://stackoverflow.com/questions/10790737/why-would-code-actively-try-to-prevent-tail-call-optimization

반응형