Загружаем каталог…
Загружаем каталог…
꼬리 호출 최적화는 오래된 아이디어지만, 필요한 호출 형태를 컴파일러가 지원하는지는 별도로 확인해야 합니다. 다음 명령으로 제어를 반복해서 넘기는 인터프리터에서는 그 지원 범위가 명령을 구성하는 방식에도 영향을 줍니다. 따라서 도입의 기준은 최적화의 존재 여부보다 현재 빌드 조건에서 실제 디스패치 구조를 구현할 수 있는지에 있습니다. 꼬리 호출은 무엇을 바꾸나요? 꼬리 호출 최적화는 함수의 마지막 호출을 점프로 바꿀 수 있게 하는 최적화입니다. 핵심 조건은 호출받은 함수가 실행을 마친 뒤 현재 함수가 더 처리할 일이 없어야 한다는 점입니다. 코드의 마지막 줄에 호출을 배치하는 것만으로는 이 조건을 충족했다고 판단하기 어렵습니다. LWN의 「Tail-call optimization in C is relatively recent」 에서 anton은 과거 C 컴파일러의 제약과 이후 확인한 변화를 설명합니다. 2025년 8월 21일 작성된 이 독자 토론은 C의 꼬리 호출 최적화가 언제 처음 등장했는지보다, 작성자가 필요로 한 호출 형태가 언제 지원됐는지에 초점을 맞춰 읽어야 합니다. 인터프리터에 적용할 때도 질문은 같습니다. 마지막 호출이라는 소스 코드의 형태가 실제로 어떤 제어 이동으로 바뀌는지 확인해야 합니다. 호출 뒤에 정리가 남는 이유 호출자에게 스택 인자를 정리할 책임이 남아 있다면, 마지막 호출 뒤에도 수행할 작업이 존재합니다. anton은 과거 C에서 호출자가 스택에 넣은 인자를 직접 정리하던 호출 관례를 사례로 듭니다. 그가 사용한 예인 int f(); 는 당시 매개변수 정보를 명시하지 않는 선언입니다. 전달한 인자가 실제 매개변수보다 많을 수 있는 상황에서는 호출받은 함수가 임의로 스택 인자를 정리하기 어려울 수 있습니다. 함수 호출 → 호출받은 함수의 실행 → 호출자의 인자 정리 → 반환 이 경우 호출자에게 돌아온 뒤 해야 할 일이 있으므로, 단순히 다음 함수로 제어를 넘기는 형태로 바꾸는 데 제약이 생깁니다. 다만 이는 작성자가 설명한 과거의 호출 관례에 관한 이야기입니다. 모든 C 실행 환경에 동일하게 적용되는 규칙으로 일반화해서는 안 됩니다. 확인 대상은 호출의 위치뿐 아니라 호출 규약과 인자 전달 방식입니다. 기계어 수준에서도 남은 정리 작업이 없는지 살펴야 최적화 가능성을 판단할 수 있습니다. 간접 호출이 중요한 이유 다음 명령의 처리 함수를 실행 중에 선택하는 인터프리터에는 간접 호출의 꼬리 호출 최적화가 필요합니다. 명령을 각각의 함수로 구현하고 다음 처리 함수를 꼬리 호출하는 구조를 생각할 수 있습니다. 이때 호출 대상은 소스 코드에 고정되지 않고 런타임에 선택될 수 있습니다. 고정된 대상을 호출하는 경우만 최적화된다면, 이러한 명령 디스패치를 구현하는 데 충분하지 않습니다. 현재 명령 처리 → 런타임의 다음 처리 함수 선택 → 간접 꼬리 호출 → 다음 명령 처리 호출 형태 호출 대상의 결정 토론에서 짚은 지원 조건 직접 호출 소스 코드에 고정 이 형태의 지원만으로는 부족 간접 호출 런타임에 선택 함수 간 디스패치에도 최적화 필요 anton이 설명한 과거 최적화의 한계에는 간접 호출을 처리하지 못한다는 점이 포함됩니다. 따라서 직접 호출을 간단히 시험한 결과를 인터프리터 전체에 그대로 적용할 수는 없습니다. 설계에서 사용할 호출 형태 자체가 시험에 들어가야 합니다. 지원 이력과 현재 환경의 차이 작성자의 재시험 결과는 설계를 다시 검토할 근거이지만, 개별 빌드 환경에서의 동작을 보장하지는 않습니다. anton은 1994년에 살펴본 C 컴파일러들이 자신에게 필요한 형태를 최적화하지 못했다고 회고합니다. 이어 2001년 Mark Probst가 별도 호출 규약으로 GCC에 꼬리 호출 최적화를 구현한 작업을 소개합니다. 이는 그 이전 GCC에 관련 최적화가 전혀 없었다는 의미가 아닙니다. 토론에서는 당시 존재하던 최적화와 그 지원 범위의 한계를 구분합니다. 이후 anton은 GCC의 계산된 점프인 goto * 를 사용하면서 꼬리 호출 지원 상황을 계속 살피지는 않았다고 설명합니다. 그러다 Xu와 Kjolstad의 「Copy-and-Patch Compilation」을 읽고 필요한 형태를 다시 시험했으며, GCC와 Clang에서 동작했다고 보고합니다. 다만 원문에 소개된 글에는 정확한 컴파일러 버전, 옵션, 재현 코드가 제시되지 않습니다. 따라서 이 경험담은 과거의 제약을 재점검할 계기로 삼을 수 있지만, 현재 사용하는 설정에 대한 검증을 대신하지는 못합니다. 코드 조각 수가 뜻하는 것 토론에 등장하는 코드 조각 수의 차이는 실행 속도보다 구현 선택지의 규모를 설명합니다. anton의 설명에 따르면 Xu와 Kjolstad의 작업은 100,000개의 코드 조각을 사용합니다. 자신들이 Gforth에서 다루는 조각은 2,000개 미만이며, 가상 머신 명령뿐 아니라 스택 캐싱 변형과 정적 슈퍼인스트럭션도 여기에 포함됩니다. 비교 대상 작성자가 밝힌 코드 조각 수 Xu와 Kjolstad의 작업 100,000개 Gforth에서 다루는 조각 2,000개 미만 이 수치를 두 구현의 성능 순위로 읽어서는 안 됩니다. anton이 주목한 것은 기존 goto * 기반 시스템에서 조각 종류가 너무 많아 적용하기 어려웠던 기법을 다시 고려할 가능성입니다. 더 많은 조각을 다룰 수 있다면 명령 변형을 구성하는 선택지도 달라질 수 있다는 설명입니다. 또한 anton은 해당 방식을 아직 Gforth에 적용하지 못했다고 밝힙니다. 그러므로 이 사례는 Gforth의 성능 개선 결과가 아니라, 컴파일러 지원을 확인한 뒤 설계 가능성을 재검토한 과정으로 이해해야 합니다. 내장 함수를 명령으로 다루기 꼬리 호출 디스패치는 내장 함수와 일반 명령을 같은 실행 구조에서 다루는 데 활용된 사례가 있습니다. 2025년 8월 23일 댓글에서 lafp는 Forth 변형 언어의 작은 인터프리터에 꼬리 호출 기반 명령 디스패치를 사용했다고 설명합니다. 그가 꼽은 이점은 별도의 내장 함수 호출 명령을 마련하는 대신, 내장 함수 자체를 명령처럼 동작하게 할 수 있었다는 점입니다. lafp의 설명에 따르면 이 구조에서는 슈퍼인스트럭션도 함께 다루기 쉬워집니다. 이 사례가 보여 주는 가치는 확인되지 않은 속도 향상 수치보다, 내장 함수에 대한 별도 처리를 줄일 수 있는 실행 구조에 있습니다. 그는 성능을 긍정적으로 평가하면서도 목표를 달성하려면 최적화기를 더 개선해야 한다고 덧붙입니다. 개인 구현에서 얻은 경험이므로 다른 인터프리터에서도 같은 효과가 난다고 확대할 수는 없습니다. 구조상의 이점과 성능 평가는 각각 확인할 대상입니다. 맞는 경우와 맞지 않는 경우 명령 구성이나 내장 함수 처리 방식을 바꾸려는 목적이 분명할 때 이 접근을 검토할 만합니다. 예를 들어 명령마다 함수를 두고 런타임에 선택한 다음 함수를 호출하려는 설계라면, 간접 꼬리 호출 지원은 직접적인 검토 대상입니다. 기존 구조에서 명령 변형의 종류를 늘리기 어렵거나, 내장 함수를 일반 명령과 비슷하게 다루고 싶을 때도 토론의 사례를 참고할 수 있습니다. 다만 필요한 호출 형태가 현재 빌드 조건에서 성립하는지 먼저 확인해야 합니다. 반대로 직접 호출의 최적화만 확인한 상태라면 간접 호출 기반 디스패치의 도입 근거로 삼기 어렵습니다. 코드 조각 수가 많다는 이유만으로 속도 향상을 기대하거나, 작성자의 GCC·Clang 시험 결과를 자신의 환경에 그대로 적용하는 판단도 근거가 부족합니다. 적합성을 가르는 기준은 최적화 이름 자체가 아닙니다. 바꾸려는 구조가 무엇인지, 그리고 그 구조에 필요한 호출을 컴파일러가 실제로 지원하는지가 기준입니다. 도입 전 검토 항목 원문을 바탕으로 정리한 검토 항목(예시) 다음 질문은 토론의 경험과 원문의 검증 제안을 실제 구현 검토에 옮긴 것입니다. 토론에서 이미 통과한 시험 목록을 뜻하지 않습니다. 작은 재현 코드에 실제 디스패치처럼 런타임에 다음 처리 함수를 선택하는 간접 호출을 포함했나요? 현재 사용하는 컴파일러 버전과 옵션에서 필요한 호출 형태의 최적화를 확인했나요? 생성된 코드에서 호출과 반환이 어떻게 이어지며, 호출자에게 어떤 정리 작업이 남는지 살폈나요? 긴 명령 실행에서도 스택 사용이 의도한 방식으로 유지되는지 확인했나요? 동일한 작업의 실행 시간과 명령 변형을 추가하는 부담을 각각 평가했나요? 내장 함수와 일반 명령 사이의 특별 처리가 실제로 줄어드는지 확인했나요? 검토 목적은 실행 비용과 구조 변화의 효과를 구분하는 데 있습니다. 명령 변형을 더 쉽게 추가할 수 있다는 결과와 동일한 작업이 더 빨라졌다는 결과는 별도로 확인해야 합니다. 코드 조각의 수용 규모만으로 성능을 대신 판단하지 않는 것이 핵심입니다. 오래된 전제를 다시 시험하기 C의 꼬리 호출 최적화는 필요한 호출 형태가 지원될 때 인터프리터의 명령 구성 방식을 재검토할 근거가 됩니다. 이 토론이 제시하는 방향은 과거에 확인한 컴파일러의 한계를 고정된 전제로 두지 않고, 현재 빌드 조건에서 실제 디스패치부터 다시 검증하는 것입니다. 원문: webi 기술 블로그 참고한 자료: Tail-call optimization in C is relatively recent AI 에이전트 생애주기 관리의 새 접근법, ADLC의 부상 위성사진으로 확인된 이스라엘의 가자지구 진입 확대, 휴전에도 계속됨
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
C 꼬리 호출 최적화, 인터프리터 설계에 쓰려면 무엇을 확인해야 할까요?. 꼬리 호출 최적화는 오래된 아이디어지만, 필요한 호출 형태를 컴파일러가 지원하는지는 별도로 확인해야 합니다. 다음 명령으로 제어를 반복해서 넘기는 인터프리터에서는 그 지원 범위가 명령을 구성하는 방식에도 영향을 줍니다. 따라서 도입의 기준은 최적화의 존재 여부보다 현재 빌드 조건에서 실제 디스패치 구조를 구현할 수 있는지에 있습니다. 꼬리 호출은 무엇을 바꾸나요? 꼬리 호출 최적화는 함수의 마지막 호출을 점프로 바꿀 수 있게 하는 최적화입니다. 핵심 조건은 호출받은 함수가 실행을 마친 뒤 현재 함수가 더 처리할 일이 없어야 한다는 점입니다. 코드의 마지막 줄에 호출을 배치하는 것만으로는 이 조건을 충족했다고 판단하기 어렵습니다.…
Открыть источник