적시 컴파일

Just-in-time compilation

컴퓨팅에서 JIT(Just-in-Time) 컴파일(동적 변환 또는 런타임 컴파일)[1]은 실행 [2]전이 아닌 실행 시(실행 시) 컴파일을 수반하는 컴퓨터 코드 실행 방법입니다.이는 소스 코드 변환으로 구성될 수 있지만 일반적으로 바이트 코드 변환에서 머신 코드로 변환되어 직접 실행됩니다.JIT 컴파일러를 구현하는 시스템은 일반적으로 실행 중인 코드를 지속적으로 분석하여 컴파일 또는 재컴파일을 통해 얻을 수 있는 속도가 해당 코드를 컴파일하는 데 드는 오버헤드를 초과하는 코드의 일부를 식별합니다.

JIT 컴파일은 머신 코드로의 변환에 관한 기존의 2가지 어프로치(AOT)와 해석의 조합으로,[2] 양쪽의 장점과 단점을 조합한 것입니다.대략적으로 JIT 컴파일은 컴파일된 코드의 속도와 해석의 유연성을 조합하여 인터프리터의 오버헤드와 컴파일 및 링크(통역뿐 아니라)의 추가 오버헤드를 실현합니다.JIT 컴파일은 동적 컴파일의 한 형태로 동적 재컴파일마이크로아키텍처 고유의 속도 [nb 1][3]향상과 같은 적응형 최적화가 가능합니다.해석 및 JIT 컴파일은 런타임 시스템이 지연된 데이터 유형을 처리하고 보안 보증을 적용할 수 있기 때문에 동적 프로그래밍 언어에 특히 적합합니다.

역사

가장 먼저 출판된 JIT 컴파일러는 일반적으로 [4]1960년 John McCarthyLISP에서 작업한 것으로 알려져 있습니다.심볼 표현의 재귀 함수 기계별 계산 파트 I에서 그는 런타임 중에 변환되는 함수를 언급함으로써 컴파일러 출력을 펀치[5] 카드에 저장할 필요가 없습니다(이것은 "컴파일 시스템"이라고 더 정확하게 알려져 있습니다).또 다른 초기 예는 Ken Thompson에 의해 1968년에 텍스트 에디터 QED[6]패턴 매칭을 위해 정규 표현식의 첫 번째 응용 프로그램 중 하나를 제공한 것입니다.속도를 위해 Thompson은 J에 의한 정규 표현 매칭을 구현했다.Compatible Time-Sharing [4]System의 IBM 7094에 대한 IT 코드.해석에서 컴파일된 코드를 도출하기 위한 영향력 있는 기술은 제임스 G에 의해 개척되었다. 1970년에 Mitchell은 실험 언어 [7][8]LC²를 구현했습니다.

Smalltalk(1983년경)는 JIT 편찬의 새로운 측면을 개척했다.예를 들어, 기계 코드로의 변환은 온 디맨드로 실행되어 나중에 사용할 수 있도록 캐시되었습니다.메모리가 부족하면 시스템은 이 코드 중 일부를 삭제하고 다시 필요할 [2][9]때 재생성합니다.Sun's Self language는 이러한 기술을 광범위하게 개선했으며, 최적화된[10] C의 최대 절반의 속도를 달성하면서도 완전한 객체 지향 언어를 갖춘 세계에서 가장 빠른 Smalltalk 시스템이었다.

Self는 Sun에게 버림받았지만, 연구는 Java 언어로 진행되었습니다."Just-in-time compilation"이라는 용어는 제조 용어 "Just-in-time"에서 차용되어 Java에 의해 대중화되었으며,[11] James Gosling은 1993년부터 이 용어를 사용했다.현재 J대부분Java Virtual Machine 구현에서 ITing을 사용하고 있으며, HotSpot은 이 연구기반을 기반으로 구축되어 광범위하게 사용되고 있습니다.

HP 프로젝트 Dynamo는 '바이트 코드' 형식과 기계 코드 형식이 동일한 실험적인 JIT 컴파일러였습니다. 시스템은 PA-6000 기계 코드를 PA-8000 기계 [12]코드로 변환했습니다.이는 직설적으로 기계 코드레벨에서 최적화를 허용했기 때문에 30%의 속도 향상을 초래했습니다.예를 들어 캐시 사용률 향상과 동적 라이브러리에 대한 호출 최적화 및 기존 컴파일러가 [13][14]시도할 수 없었던 많은 다른 런타임 최적화를 위한 코드 인라이닝이 가능했기 때문입니다.

2020년 11월, PHP 8.0은 JIT [15]컴파일러를 도입했다.

설계.

바이트 코드 컴파일 시스템에서 소스 코드는 바이트 코드라고 알려진 중간 표현으로 변환된다.바이트 코드는 특정 컴퓨터의 기계 코드가 아니며 컴퓨터 아키텍처 간에 휴대할 수 있습니다.그런 다음 가상 시스템에서 바이트 코드를 해석하거나 실행할 수 있습니다.JIT 컴파일러는 많은 섹션(또는 드물게 전체)에서 바이트 코드를 읽고 이를 기계 코드로 동적으로 컴파일하여 프로그램을 더 빠르게 실행할 수 있도록 합니다.이것은 파일 단위, 함수 단위, 또는 임의의 코드 프래그먼트 상에서 실행할 수 있습니다.코드는 실행 직전에 컴파일(따라서 "just-in-time"이라는 이름)한 후 나중에 캐시 및 재사용할 수 있습니다.

반면 기존의 해석된 가상 머신은 바이트 코드를 단순히 해석할 뿐이며, 일반적으로 성능이 훨씬 떨어집니다.일부 인터프리터는 바이트 코드로 컴파일하는 단계 없이 소스 코드를 해석하기도 합니다.그 때문에, 퍼포먼스는 한층 더 나빠집니다.스태틱 컴파일된 코드 또는 네이티브코드는 도입 전에 컴파일 됩니다.동적 컴파일 환경은 실행 중에 컴파일러를 사용할 수 있는 환경입니다.JIT 기술을 사용하는 일반적인 목표는 바이트 코드 해석의 장점을 유지하면서 정적 컴파일의 성능에 도달하거나 이를 능가하는 것입니다.원래 소스 코드를 해석하고 기본적인 최적화를 실행하는 "중요한 작업"의 대부분은 도입 전 컴파일 시에 처리됩니다.바이트 코드에서 머신 코드로의 컴파일은 소스로부터의 컴파일보다 훨씬 빠릅니다.배치된 바이트 코드는 네이티브 코드와 달리 이식 가능합니다.런타임은 해석된 바이트 코드와 같이 컴파일을 제어할 수 있으므로 안전한 샌드박스에서 실행할 수 있습니다.휴대용 바이트 코드 컴파일러가 이미 많은 작업을 수행했기 때문에 바이트 코드부터 기계 코드까지 컴파일러는 쓰기 더 쉽습니다.

일반적으로 JIT 코드는 인터프리터보다 훨씬 뛰어난 성능을 제공합니다.또한 많은 최적화가 [16][17]런타임에만 가능하기 때문에 정적 컴파일보다 뛰어난 성능을 제공할 수 있습니다.

  1. 컴파일은 대상 CPU 및 응용 프로그램이 실행되는 운영 체제 모델에 맞게 최적화할 수 있습니다.예를 들어 JIT는 SSE2 벡터 CPU 명령을 CPU가 지원하는 것을 검출했을 때 해당 명령을 선택할 수 있습니다.스태틱 컴파일러에서 이 수준의 최적화 특성을 얻으려면 의도된 플랫폼/아키텍처별로 바이너리를 컴파일하거나 단일 바이너리 내에 코드의 여러 버전을 포함해야 합니다.
  2. 시스템은 현재 환경에서 프로그램이 실제로 어떻게 실행되고 있는지에 대한 통계를 수집할 수 있으며 최적의 성능을 위해 재배치 및 재컴파일할 수 있습니다.단, 일부 정적 컴파일러는 프로파일 정보를 입력으로 사용할 수도 있습니다.
  3. 시스템은 동적 링크의 장점을 잃지 않고 정적 컴파일러 및 링커 고유의 오버헤드 없이 글로벌 코드 최적화(라이브러리 기능 인라인화 등)를 수행할 수 있습니다.구체적으로는 글로벌인라인 치환을 실행할 때 정적 컴파일프로세스에 런타임체크가 필요할 수 있으며 오브젝트의 실제 클래스가 인라인 메서드를 덮어쓰면 가상 콜이 발생하며 어레이 액세스 경계 조건 체크를 루프 내에서 처리해야 할 수 있습니다.적시 컴파일을 사용하면 대부분의 경우 이 처리를 루프에서 벗어나 고속화할 수 있습니다.
  4. 이것은 정적으로 컴파일된 가비지 수집 언어에서는 가능하지만, 바이트 코드 시스템은 캐시 사용률을 높이기 위해 실행된 코드를 더 쉽게 재배치할 수 있습니다.

JIT는 런타임에 네이티브 바이너리 이미지를 렌더링 및 실행해야 하므로 진정한 머신 코드 JIT에서는 런타임에 데이터를 실행할 수 있는 플랫폼이 필요합니다.이 때문에 하버드 아키텍처 기반의 머신에서는 이러한 JIT를 사용할 수 없습니다.특정 운영체제나 가상 머신에서도 마찬가지입니다.단, 특정 유형의 "JIT"는 잠재적으로 물리적 머신의 CPU 아키텍처를 대상으로 하는 것이 아니라 원시 머신 코드에 대한 제한이 널리 적용되는 최적화된 VM 바이트 코드를 대상으로 할 수 있습니다. 특히 해당 바이트 코드의 VM이 최종적으로 네이티브 [18]코드에 대한 JIT를 활용하는 경우에는 더욱 그렇습니다.

성능

JIT는 바이트 코드를 로드하고 컴파일하는 데 시간이 걸리기 때문에 응용 프로그램의 초기 실행이 약간 또는 현저하게 지연됩니다.이 지연을 "시작 시간 지연" 또는 "예열 시간"이라고 부르는 경우가 있습니다.일반적으로 JIT가 최적화를 더 많이 수행할수록 코드가 더 잘 생성되지만 초기 지연도 증가합니다.따라서 JIT 컴파일러는 컴파일 시간과 생성하려는 코드의 품질 사이에서 균형을 맞춰야 합니다.기동 시간에는, JIT 컴파일에 가세해 IO 바인딩 조작의 증가를 포함할 수 있습니다.예를 들어 Java Virtual Machine(JVM; Java 가상 머신)의 rt.jar 클래스 데이터 파일은 40 MB이며, JVM은 컨텍스트적으로 큰 [19]파일 내에서 대량의 데이터를 요구해야 합니다.

Sun의 HotSpot Java Virtual Machine에서 사용할 수 있는 최적화 중 하나는 해석과 JIT 컴파일을 결합하는 것입니다.애플리케이션 코드는 처음에는 해석되지만 JVM은 어떤 바이트 코드의 시퀀스가 자주 실행되는지 감시하고 하드웨어에서 직접 실행할 수 있도록 머신 코드로 변환합니다.몇 번만 실행되는 바이트 코드의 경우 컴파일 시간을 절약하고 초기 지연 시간을 줄입니다.또한 자주 실행되는 바이트 코드의 경우 느린 해석의 초기 단계 후 JIT 컴파일을 사용하여 고속으로 실행됩니다.또한 프로그램은 코드의 소수를 실행하는 데 대부분의 시간을 소비하기 때문에 컴파일 시간이 크게 단축됩니다.마지막으로, 초기 코드 해석 중에 컴파일 전에 실행 통계를 수집할 수 있으므로 최적화를 [20]더 잘 수행할 수 있습니다.

올바른 트레이드오프는 상황에 따라 다를 수 있습니다.예를 들어 Sun의 Java Virtual Machine에는 클라이언트와 서버의 두 가지 주요 모드가 있습니다.클라이언트 모드에서는 최소한의 컴파일 및 최적화가 실행되어 부팅 시간이 단축됩니다.서버 모드에서는 광범위한 컴파일 및 최적화가 수행되므로 시작 시간을 단축하여 애플리케이션 실행 시 성능을 극대화할 수 있습니다.다른 Java Just-in-Time 컴파일러는 메서드가 실행한 횟수와 메서드의 바이트 코드 크기를 조합한 런타임 측정을 휴리스틱으로 사용하여 [21]컴파일 시기를 결정합니다.또,[22] 루프 검출과 조합해 실행 회수를 사용하는 것도 있습니다.일반적으로 단기 어플리케이션에서는 장기 어플리케이션보다 어떤 [23]방법을 최적화할지를 정확하게 예측하기가 훨씬 어렵습니다.

MicrosoftNative Image Generator(Ngen)는 초기 [24]지연을 줄이기 위한 또 다른 방법입니다.Ngen은 공통 중간 언어 이미지의 바이트 코드를 기계 네이티브 코드로 사전 컴파일합니다.따라서 런타임 컴파일이 필요하지 않습니다.Visual Studio 2005와 함께 제공된 NET Framework 2.0은 설치 직후 모든 Microsoft 라이브러리 DLL에서 Ngen을 실행합니다.프리짓은 기동 시간을 단축하는 방법을 제공합니다.단, 생성되는 코드의 품질은 J 코드만큼 좋지 않을 수 있습니다.프로파일 가이드 최적화 없이 정적으로 컴파일된 코드가 극단적인 경우 JIT 컴파일된 코드만큼 우수할 수 없는 것과 같은 이유로 ITed는 인라인 [25]캐싱과 같이 구동할 프로파일링 데이터가 없습니다.

또한 AOT(Ahead-of-time) 컴파일러를 JIT 컴파일러(Excelsior JET) 또는 인터프리터(GNU Compiler for Java)와 결합하는 Java 구현도 있습니다.

보안.

JIT 컴파일은 기본적으로 실행 가능한 데이터를 사용하기 때문에 보안상의 과제와 악용 가능성이 있습니다.

JIT 컴파일의 실장은 소스 코드 또는 바이트 코드를 기계 코드에 컴파일하여 실행하는 것으로 구성됩니다.이것은 일반적으로 메모리에서 직접 실행됩니다.JIT 컴파일러는 머신 코드를 디스크에 출력하여 컴파일 전에 다른 프로그램으로 호출하는 것이 아니라 머신 코드를 메모리에 직접 출력하고 즉시 실행합니다.최신 아키텍처에서는 실행 가능한 공간 보호로 인해 문제가 발생합니다.즉, 임의의 메모리를 실행할 수 없습니다.그렇지 않으면 잠재적인 보안상의 구멍이 생깁니다.따라서 메모리는 실행 가능한 것으로 표시되어야 합니다.보안상의 이유로 코드를 메모리에 쓴 후에 실행 가능한 것으로 표시해야 합니다.쓰기 가능/실행 가능한 메모리는 보안 구멍입니다(W^X [26]참조).예를 들어 Firefox의 JIT 컴파일러 for Javascript는 Firefox [27]46과 함께 릴리스 버전에서 이 보호 기능을 도입했습니다.

JIT 스프레이는 J를 사용하는 컴퓨터 보안 공격 클래스입니다.IT 컴파일(히프 분무용): 결과 메모리를 실행 가능.이것에 의해, 실행이 힙내로 이동할 수 있는 경우에 악용할 수 있습니다.

사용하다

JIT 컴파일은 일부 프로그램에 적용하거나 특정 용량(특히 정규 표현과 같은 동적 용량)에 사용할 수 있습니다.예를 들어 텍스트 에디터는 실행 시 제공된 정규식을 머신 코드에 컴파일하여 보다 빠른 매칭을 가능하게 할 수 있습니다.패턴이 실행 시에만 제공되기 때문에 이 작업은 사전에 수행할 수 없습니다.대부분의 Java 구현을 포함하여 여러 최신 런타임 환경에서 고속 코드 실행을 위해 마이크로소프트와 함께 JIT 컴파일을 사용합니다.NET. 마찬가지로 많은 정규 표현 라이브러리는 바이트 코드 또는 기계 코드 중 하나로 정규 표현의 JIT 컴파일을 제공합니다.JIT 컴파일은 CPU 아키텍처 간에 머신 코드를 변환하기 위해 일부 에뮬레이터에서도 사용됩니다.

JIT 컴파일의 일반적인 구현은 먼저 바이트 코드(바이트 코드 컴파일로 알려진)에 대한 AOT 컴파일을 실시하고 다음으로 바이트 코드 해석 대신 기계 코드에 대한 JIT 컴파일(동적 컴파일)을 수행하는 것입니다.이렇게 하면 컴파일로 인한 지연을 감수하면서 해석에 비해 런타임 성능이 향상됩니다.JIT 컴파일러는 인터프리터와 마찬가지로 지속적으로 번역하지만 컴파일된 코드를 캐싱하면 특정 실행 중에 동일한 코드를 실행할 때 지연이 최소화됩니다.프로그램의 일부만 컴파일되기 때문에 전체 프로그램이 실행되기 전에 컴파일된 경우보다 지연이 크게 줄어듭니다.

「 」를 참조해 주세요.

메모들

  1. ^ 선행 컴파일러는 특정 마이크로아키텍처를 대상으로 할 수도 있지만, 그 점에서 AOT와 JIT의 차이는 휴대성에 있습니다.JIT는 실행 시 현재 실행 중인 CPU에 맞춘 코드를 렌더링할 수 있지만, AOT는 uarch의 일반화된 서브셋에 대해 최적화하는 대신 타깃 CPU를 미리 알아야 합니다.이러한 코드는 다른 CPU 타입에서는 퍼포먼스가 저하될 수 있을 뿐만 아니라 완전히 불안정할 수 있습니다.

레퍼런스

  1. ^ Languages, Compilers, and Runtime Systems, University of Michigan, Computer Science and Engineering, retrieved March 15, 2018
  2. ^ a b c Aycock 2003.
  3. ^ "Does the JIT take advantage of my CPU?". David Notario's WebLog. Retrieved 2018-12-03.
  4. ^ a b Aycock 2003, 2. JIT 컴파일 기법, 2.1 Genesis, 페이지 98.
  5. ^ McCarthy, J. (April 1960). "Recursive functions of symbolic expressions and their computation by machine, Part I". Communications of the ACM. 3 (4): 184–195. CiteSeerX 10.1.1.111.8833. doi:10.1145/367177.367199. S2CID 1489409.
  6. ^ 톰슨 1968년
  7. ^ Aycock 2003, 2. JIT 컴파일 기법, 2.2 LC², 페이지 98~99.
  8. ^ Mitchell, J.G. (1970). "The design and construction of flexible and efficient interactive programming systems". {{cite journal}}:Cite 저널 요구 사항 journal=(도움말)
  9. ^ Deutsch, L.P.; Schiffman, A.M. (1984). "Efficient implementation of the Smalltalk-80 system" (PDF). POPL '84: Proceedings of the 11th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages: 297–302. doi:10.1145/800017.800542. ISBN 0-89791-125-3. S2CID 3045432. Archived from the original (PDF) on 2004-06-18.
  10. ^ "Archived copy". research.sun.com. Archived from the original on 24 November 2006. Retrieved 15 January 2022.{{cite web}}: CS1 maint: 제목으로 아카이브된 복사(링크)
  11. ^ Aycock 2003, 2.14 Java, 107페이지, 각주 13.
  12. ^ "Dynamo: 투과적인 동적 최적화 시스템"바산스 발라, 에블린 뒤스터왈드, 산지예프 바네르지아PLDI '00 프로그래밍 언어 설계 및 구현에 관한 ACM SIGPLAN 2000 회의 진행.1 ~ 12 페이지DOI 10.1145/349299.349303. 2012년 3월 28일 취득
  13. ^ John Jannotti. "HP's Dynamo". Ars Technica. Retrieved 2013-07-05.
  14. ^ "The HP Dynamo Project". Archived from the original on October 19, 2002. Retrieved 2016-04-12.{{cite web}}: CS1 유지보수: 부적합한 URL(링크)
  15. ^ Tung, Liam (27 November 2020). "Programming language PHP 8 is out: This new JIT compiler points to better performance". ZDNet. Retrieved 28 November 2020.
  16. ^ Croce, Louis. "Just in Time Compilation" (PDF). Columbia University. Archived from the original (PDF) on 2018-05-03.
  17. ^ "What are the advantages of JIT vs. AOT compilation". Stack Overflow. Jan 21, 2010.
  18. ^ "Compile a JIT based lang to Webassembly". Stack Overflow. Retrieved 2018-12-04.
  19. ^ Haase, Chet (May 2007). "Consumer JRE: Leaner, Meaner Java Technology". Sun Microsystems. Retrieved 2007-07-27.
  20. ^ "The Java HotSpot Performance Engine Architecture". Oracle.com. Retrieved 2013-07-05.
  21. ^ Schilling, Jonathan L. (February 2003). "The simplest heuristics may be the best in Java JIT compilers" (PDF). SIGPLAN Notices. 38 (2): 36–46. doi:10.1145/772970.772975. S2CID 15117148. Archived from the original (PDF) on 2015-09-24.
  22. ^ 스가누마 도시오, 야스에 토시아키, 카와히토 모토히로, 코마츠 히데아키, 나카타니 도시오, 「Java Just-in-Time 컴파일러의 동적 최적화 프레임워크」, 제16회 ACM SIGPLAN 회의의 진행, 오브젝트 지향 프로그래밍 시스템, 언어, 어플리케이션(OPS) 01.
  23. ^ Matthew Arnold, Michael Hind, Barbara G. Ryder, "선택적 최적화의 경험적 연구", 병렬 컴퓨팅 개정 논문의 언어 컴파일러에 관한 제13회 국제 워크숍 진행, 페이지 49~67, 2000년 8월 10~12일.
  24. ^ "Native Image Generator (Ngen.exe)". Msdn2.microsoft.com. Retrieved 2013-07-05.
  25. ^ Sweeney, Arnold (February 2005). "A Survey of Adaptive Optimization in Virtual Machines" (PDF). Proceedings of the IEEE. 92 (2): 449–466. Archived from the original (PDF) on 2016-06-29.
  26. ^ "How to JIT – an introduction", Eli Bendersky, 2013년 11월 5일 오전 5시 59분
  27. ^ De Mooij, Jan. "W^X JIT-code enabled in Firefox". Jan De Mooij. Retrieved 11 May 2016.

추가 정보

외부 링크