통화 최적화를 위한 최적화
저는 C가 테일 콜 제거를 수행하지 않는다는 말을 자주 듣습니다.기준상 보장되지는 않지만, 어쨌든 제대로 된 실행에 의해 실제 실행되고 있지 않습니까?성숙하고 잘 구현된 컴파일러만을 대상으로 하고 불분명한 플랫폼을 위해 작성된 프리미티브 컴파일러에 대한 절대 최대 이식성은 신경 쓰지 않는다고 가정할 때, C에서 테일콜 제거에 의존하는 것이 합리적입니까?
또한 테일 콜 최적화를 표준에서 제외한 이유는 무엇입니까?
"C는 테일 콜 제거를 수행하지 않습니다."와 같은 문장은 말이 되지 않습니다.여러분이 정확히 지적하셨듯이, 이와 같은 것들은 전적으로 구현에 달려 있습니다.예, 어떤 적절한 구현이든 꼬리 재귀를 [동등한] 사이클로 쉽게 전환할 수 있습니다.물론 C 컴파일러는 각 특정 코드에서 어떤 최적화가 이루어지고 어떤 최적화가 일어나지 않을 것인지에 대해 일반적으로 보장하지 않습니다.당신이 직접 정리해서 봐야 합니다.
최적화 기능을 설정하면 현대 컴파일러가 테일콜 최적화를 수행할 수 있지만, 디버그 빌드는 스택 추적 및 코드 입력/아웃과 같은 훌륭한 기능을 얻을 수 있도록 이 기능 없이 실행될 가능성이 높습니다.이런 상황에서는 테일콜 최적화가 필요하지 않습니다.
테일콜 최적화가 항상 바람직하지는 않기 때문에 컴파일러 작성자에게 이를 의무화하는 것은 타당하지 않습니다.
많은 재귀가 예상되거나 요구되는 경우, 즉 기능적인 프로그래밍 스타일을 권장하거나 강제하는 언어에서만 테일콜 최적화가 보장되어야 한다고 생각합니다. (이러한 언어를 사용하면, 당신은 다음과 같은 것을 알 수 있습니다.for
아니면while
루프는 강하게 억제되거나, 우아하지 않은 것으로 인식되거나, 언어에서 완전히 벗어나므로 이러한 모든 이유와 아마도 더 많은 이유로 재귀에 의존하게 될 것입니다.)
C 프로그래밍 언어(IMHO)는 분명히 기능적 프로그래밍을 염두에 두고 설계되지 않았습니다.일반적으로 재귀를 위해 사용되는 모든 종류의 루프 구조가 있습니다.for
,do .. while
,while
콜 은 큰 것입니다. 이러한 언어에서는 작업 프로그램을 엄격하게 보장할 필요가 없기 때문에 테일 콜 최적화를 표준으로 규정하는 것은 큰 의미가 없을 것입니다.
을 과 하지 와 합니다 합니다 을 과 while
루프: 이것은 재귀가 필요하다는 것을 의미합니다. 이것은 또한 언어가 많은 반복을 통해 스택 오버플로가 문제가 되지 않도록 해야 한다는 것을 의미합니다. 따라서 이러한 언어의 공식 표준은 테일 콜 최적화를 규정하는 것을 선택할 수 있습니다.
추신: 테일콜 최적화를 위한 제 주장에 약간의 결함이 있음을 주목하세요.마지막으로 스택 오버플로에 대해 언급합니다.그러나 함수 호출에는 항상 스택이 필요하다고 누가 말합니까?일부 플랫폼에서는 함수 호출이 완전히 다른 방식으로 구현될 수 있으며 스택 오버플로는 문제가 되지 않습니다.이것은 테일 콜 최적화를 표준에 규정하는 것에 반대하는 또 다른 논거가 될 것입니다. (하지만 오해하지 마십시오. 스택이 없어도 그러한 최적화의 장점을 알 수 있습니다!)
마지막 질문에 대한 답변:표준은 최적화에 대한 어떠한 진술도 절대로 해서는 안 됩니다.구현이 다소 어려운 환경이 있을 수 있습니다.
시공에 의한 증명을 좋아하는 사람들을 위해, 멋진 테일 콜 최적화를 수행하는 godbolt를 소개합니다. https://godbolt.org/z/DMleUN
그러나 최적화를 -O3로 크랭킹하면(또는 몇 년 기다리거나 다른 컴파일러를 사용해도 의심의 여지가 없음), 최적화는 루프/재귀를 완전히 제거합니다.
다음은 -O2: https://godbolt.org/z/CNzWex 을 사용해도 단일 명령어로 최적화되는 예입니다.
언어 표준은 컴파일러가 구현되어야 하는 방식이 아니라 언어의 동작 방식을 정의합니다.최적화가 항상 필요한 것은 아니기 때문에 의무적인 것은 아닙니다.컴파일러는 사용자가 원하는 경우 최적화를 실행할 수 있도록 옵션을 제공하며, 마찬가지로 최적화를 해제할 수도 있습니다.컴파일러 최적화는 코드 디버그 기능에 영향을 줄 수 있으므로(C를 줄 단위 방식으로 어셈블리에 맞추기가 어려워짐), 사용자의 요청에 따라서만 최적화를 수행하는 것이 타당합니다.
테일 콜 최적화가 잠재적으로 ABI를 파괴하거나 최소한 의미 보존 방식으로 구현하기가 매우 어려운 상황이 있습니다.예를 들어 공유 라이브러리의 위치 독립 코드를 생각해 보십시오.다양한 응용 프로그램이 모두 동일한 기능에 의존할 때 메인 메모리를 저장하기 위해 일부 플랫폼에서는 프로그램이 라이브러리에 대해 동적으로 링크할 수 있습니다.이러한 경우 라이브러리가 한 번 로드되고 시스템의 유일한 응용 프로그램인 것처럼 프로그램의 가상 메모리 각각에 매핑됩니다.UNIX 및 일부 다른 시스템에서는 위치 독립 코드를 라이브러리에 사용하여 고정 주소 공간에 절대적인 것이 아니라 오프셋에 상대적인 주소 지정을 수행합니다.그러나 많은 플랫폼에서 위치 독립 코드는 테일 콜을 최적화해서는 안 됩니다.입니다. 는기한이에다는야을다는야e에이n한tn;semoedts기re된을-e 인텔 32비트에서는,%ebx
호출된 저장 레지스터인 를 사용합니다. 다른 플랫폼은 이 개념을 따릅니다.일반 호출을 사용하는 함수와 달리, 테일 호출을 배포하는 사람들은 자신이 돌아올 때가 아니라 서브루틴으로 분기하기 전에 호출자가 저장한 레지스터를 복원해야 합니다.일반적으로 이는 문제가 되지 않습니다. 왜냐하면 이 시점에서 최상위 호출 함수는 다음에 저장된 값을 신경 쓰지 않기 때문입니다.%ebx
, 그러나 위치 독립 코드는 각 점프, 호출 또는 분기 명령에 따라 이 값이 달라집니다.
객체 지향 언어(C++)로 정리가 보류 중인 다른 문제가 있을 수 있는데, 이는 함수의 마지막 호출이 실제로는 마지막 호출이 아니라는 것을 의미합니다. 즉, 정리는 다음과 같습니다.따라서 컴파일러는 보통 이런 경우에 최적화하지 않습니다.
또한.setjmp
그리고.longjmp
물론 문제가 있습니다. 이는 함수가 실제로 완료되기 전에 두 번 이상 실행을 완료할 수 있음을 의미하기 때문입니다.컴파일 시 최적화가 어렵거나 불가능합니다!
아마 생각할 수 있는 기술적인 이유가 더 있을 겁니다.이것들은 단지 몇 가지 고려 사항일 뿐입니다.
컴파일러들은 함수가 다른 함수를 호출한 후에 아무것도 할 필요가 없는 상황을 인식하고 그 호출을 점프로 대체하는 것이 일반적입니다.그것이 안전하게 이루어질 수 있는 많은 경우들은 쉽게 알아볼 수 있고, 그러한 경우들은 "안전하게 덜 매달린 과일"로서 자격이 있습니다.그러나 이러한 최적화를 수행할 수 있는 컴파일러에서도 언제 수행해야 하거나 수행할 것인지가 항상 명확하지는 않을 수 있습니다.다양한 요인들이 일반 통화의 비용보다 테일 콜 비용을 더 크게 만들 수 있으며, 이러한 요인들이 항상 예측 가능한 것은 아닐 수도 있습니다.예를 들어, 함수가 다음으로 끝나는 경우return foo(1,2,3,a,b,c,4,5,6);
, a, b, c를 레지스터에 복사하고 스택을 정리한 다음 인수를 통과하기 위해 준비하는 것이 실용적일 수 있지만 처리할 수 있는 레지스터가 충분하지 않을 수 있습니다.foo(a,b,c,d,e,f,g,h,i);
저도 마찬가지예요.
언어에 가능하면 테일 콜을 하고, 그렇지 않으면 컴파일을 거부하는 컴파일러가 필요한 특별한 "테일 콜" 구문이 있다면 코드는 그런 함수가 임의로 깊이 중첩될 수 있다고 안전하게 가정할 수 있습니다.그러나 일반적인 호출 구문을 사용할 때 컴파일러가 "일반적인" 것보다 더 저렴하게 후행 호출을 수행할 수 있는지 여부를 알 수 있는 일반적인 방법은 없습니다.
언급URL : https://stackoverflow.com/questions/3514283/c-tail-call-optimization
'source' 카테고리의 다른 글
(mysql 또는 펄엔드에서) sql 결과의 빈 날짜를 패드하는 가장 간단한 방법은 무엇입니까? (0) | 2023.09.14 |
---|---|
Wordpress 플러그인이 두 번 설치됨 (0) | 2023.09.14 |
API 응답에서 응답 헤더 읽기 - Angular 5 + TypeScript (0) | 2023.09.14 |
Enter-PS 세션이 내 Powershell 스크립트에서 작동하지 않습니다. (0) | 2023.09.14 |
WordPress Theme "ERROR: 테마가 상위 테마로 정의됩니다.템플릿 헤더를 확인해 주시기 바랍니다." (0) | 2023.09.14 |