Programing

Just-In-Time 컴파일과 Ahead-of-Time 컴파일의 장점은 무엇입니까?

crosscheck 2020. 11. 9. 07:48
반응형

Just-In-Time 컴파일과 Ahead-of-Time 컴파일의 장점은 무엇입니까?


나는 최근에 그것에 대해 생각하고 있으며 JIT 컴파일에 주어진 대부분의 이점 은 대체로 중간 형식에 기인해야하며, 그 자체로는 코드를 생성하는 좋은 방법이 아니라는 것 같습니다.

그래서 이것은 내가 일반적으로 듣는 주요 pro-JIT 컴파일 인수입니다.

  1. Just-in-time 컴파일은 더 큰 이식성을 허용합니다. 중간 형식에 기인하지 않습니까? 내 말은, 가상 바이트 코드를 컴퓨터에 가져 오면 가상 바이트 코드를 네이티브 바이트 코드로 컴파일하는 것을 막지 못합니다. 이식성은 '실행'단계가 아닌 '배포'단계의 문제입니다.
  2. 좋습니다. 그러면 런타임에 코드를 생성하는 것은 어떻습니까? 음, 동일하게 적용됩니다. 실제 Just-In-Time 요구를위한 Just-In-Time 컴파일러를 네이티브 프로그램에 통합하는 데 방해가되는 것은 없습니다.
  3. 그러나 런타임은 어쨌든 한 번만 네이티브 코드로 컴파일하고 결과 실행 파일을 하드 드라이브 어딘가에 일종의 캐시에 저장합니다. 그래, 그래. 그러나 그것은 시간 제약 하에서 프로그램을 최적화하고 거기에서 더 나아지지 않습니다. 다음 단락을 참조하십시오.

이 같은 아니라 앞으로-의 시간 컴파일이 하나 더 장점이 없었다. Just-in-time 컴파일에는 시간 제약이 있습니다. 프로그램이 시작되는 동안 최종 사용자를 영원히 기다리게 할 수 없으므로 어딘가에서 할 수있는 절충안이 있습니다. 대부분의 경우 그들은 덜 최적화합니다. 내 친구는 함수를 인라인하고 루프를 "수동으로"(프로세스에서 소스 코드를 난독 화) 풀면 C # 번호 처리 프로그램의 성능에 긍정적 인 영향을 미친다 프로파일 링 증거 가있었습니다 . C 프로그램이 같은 작업을 채우는 상태에서 똑같은 작업을 수행하면 긍정적 인 결과가 나오지 않았으며 이것이 내 컴파일러가 허용 한 광범위한 변환 때문이라고 생각합니다.

그럼에도 불구하고 우리는 혼란스러운 프로그램에 둘러싸여 있습니다. C #자바 는 어디에나 있고, 파이썬 스크립트는 일종의 바이트 코드로 컴파일 될 수 있으며, 다른 프로그래밍 언어들도 똑같이 할 수 있다고 확신합니다. 내가 놓친 타당한 이유가있을 것 같다. 그렇다면 Just-In-Time 컴파일이 Ahead-of-Time 컴파일 보다 뛰어난 점은 무엇일까요?


편집 약간의 혼란을 없애기 위해 실행 파일의 중간 표현을 위해 모두라고 말하는 것이 중요 할 수 있습니다. 이것은 많은 장점을 가지고 있습니다 (실제로 JIT 컴파일 대한 대부분의 인수 는 실제로 중간 표현에 대한 인수입니다). 내 질문은 네이티브 코드로 컴파일하는 방법에 관한 것입니다.

대부분의 런타임 (또는 해당 문제에 대한 컴파일러)은 Just-In-Time 또는 Ahead-of-Time 컴파일을 선호합니다. 으로 앞서-의 시간 나에게 더 나은 대안처럼 컴파일 외모 컴파일러가 최적화를 수행하는 데 더 많은 시간을 가지고 있기 때문에, 나는 마이크로 소프트, 썬과 다른 사람들은 모두 다른 방법으로 주위를가는 이유 궁금하네요. JIT (Just-In-Time) 컴파일 된 프로그램 에 대한 경험이 기본 최적화가 좋지 않았기 때문에 프로파일 링 관련 최적화에 대해 다소 모호 합니다.

나는 사전 컴파일과 Just-In-Time 컴파일 의 예제가 필요했기 때문에 C 코드로 예제를 사용했습니다 . C 코드가 중간 표현으로 내보내지지 않았다는 사실 은 상황과 무관합니다. 사전 컴파일이 더 나은 즉각적인 결과를 얻을 수 있다는 것을 보여줄 필요가 있었기 때문 입니다.


  1. 뛰어난 이식성 : 결과물 (바이트 코드)은 이식성을 유지합니다.

  2. 동시에 더 많은 플랫폼 별 : JIT 컴파일은 코드가 실행되는 동일한 시스템에서 발생하기 때문에 해당 특정 시스템에 대해 매우 미세 조정할 수 있습니다. 사전 컴파일을 수행하고 모든 사람에게 동일한 패키지를 제공하려는 경우 타협해야합니다.

  3. 컴파일러 기술의 향상은 기존 프로그램에 영향을 미칠 수 있습니다. 더 나은 C 컴파일러는 이미 배포 된 프로그램에서 전혀 도움이되지 않습니다. 더 나은 JIT 컴파일러는 기존 프로그램의 성능을 향상시킵니다. 10 년 전에 작성한 Java 코드는 오늘날 더 빠르게 실행됩니다.

  4. 런타임 메트릭에 적응. JIT 컴파일러는 코드와 대상 시스템을 볼 수있을뿐만 아니라 코드가 사용되는 방식도 볼 수 있습니다. 실행중인 코드를 계측 할 수 있으며, 예를 들어 메서드 매개 변수가 일반적으로 갖는 값에 따라 최적화 방법을 결정할 수 있습니다.

JIT가 시작 비용에 추가하는 것이 옳으며 따라서 시간 제약이있는 반면, 사전 컴파일은 원하는 모든 시간이 걸릴 수 있습니다. 이것은 시작 시간이 그다지 중요하지 않고 코드가 정말 빨라지기 전의 "준비 단계"가 허용되는 서버 유형 응용 프로그램에 더 적합합니다.

JIT 컴파일의 결과를 어딘가에 저장하여 다음에 다시 사용할 수 있다고 생각합니다. 그러면 두 번째 프로그램 실행을위한 "미리 시간"컴파일이 제공됩니다. 썬과 마이크로 소프트의 영리한 사람들은 새로운 JIT가 이미 충분하고 추가 복잡성이 문제의 가치가 없다고 생각할 수 있습니다.


NGEN 도구 페이지 콩을 유출 (또는 적어도 JIT 컴파일 된 이미지 대 네이티브 이미지의 좋은 비교를 제공). 미리 컴파일 된 실행 파일은 일반적으로 다음과 같은 이점이 있습니다.

  1. 기본 이미지는 시작 활동이 많지 않고 더 적은 메모리 (JIT 컴파일러에 필요한 메모리)가 필요하기 때문에 더 빨리로드됩니다.
  2. 네이티브 이미지는 라이브러리 코드를 공유 할 수 있지만 JIT 컴파일 이미지는 공유 할 수 없습니다.

Just-in-time 컴파일 된 실행 파일은 일반적으로 다음과 같은 경우에 유리합니다.

  1. 네이티브 이미지는 해당 바이트 코드보다 큽니다.
  2. 원본 어셈블리 또는 해당 종속성 중 하나가 수정 될 때마다 네이티브 이미지를 다시 생성해야합니다.

구성 요소 중 하나를 사용할 때마다 미리 컴파일 된 이미지를 다시 생성해야한다는 점은 네이티브 이미지 단점입니다. 반면에 JIT로 컴파일 된 이미지가 라이브러리 코드를 공유 할 수 없다는 사실은 심각한 메모리 히트를 유발할 수 있습니다. 운영 체제는 하나의 물리적 위치에서 모든 기본 라이브러리를로드하고이를 사용하려는 모든 프로세스와 변경 불가능한 부분을 공유 할 수 있으므로 특히 거의 모든 프로그램에서 사용하는 시스템 프레임 워크에서 상당한 메모리 절약 효과를 얻을 수 있습니다. (나는 이것이 JIT로 컴파일 된 프로그램이 실제로 사용하는 것만 컴파일한다는 사실에 의해 다소 상쇄된다고 생각합니다.)

이 문제에 대한 Microsoft의 일반적인 고려 사항은 큰 응용 프로그램은 일반적으로 미리 컴파일하면 이익을 얻는 반면 작은 응용 프로그램은 일반적으로 그렇지 않다는 것입니다.


간단한 논리는 바이트 코드로도 거대한 MS Office 크기 프로그램을 컴파일하는 데 너무 많은 시간이 소요된다는 것을 알려줍니다. 당신은 엄청난 시작 시간을 갖게 될 것이고 그것은 당신의 제품에서 누군가를 놀라게 할 것입니다. 물론, 설치 중에 미리 컴파일 할 수 있지만 이로 인해 결과가 발생합니다.

또 다른 이유는 응용 프로그램의 일부가 사용되지 않기 때문입니다. JIT는 사용자가 신경 쓰는 부분 만 컴파일하여 잠재적으로 코드의 80 %를 그대로 유지하여 시간과 메모리를 절약합니다.

마지막으로 JIT 컴파일은 일반 컴파일러가 할 수없는 최적화를 적용 할 수 있습니다. 인라인 가상 메소드 또는 추적 트리 가있는 메소드의 일부와 같습니다 . 이론적으로 더 빠르게 만들 수 있습니다.


  1. 더 나은 반사 지원. 이것은 원칙적으로 미리 컴파일 된 프로그램에서 수행 될 수 있지만 실제로는 거의 발생하지 않는 것 같습니다.

  2. 프로그램을 동적으로 관찰해야만 알아낼 수있는 최적화. 예를 들어 가상 함수를 인라인하고 분석을 이스케이프하여 스택 할당을 힙 할당으로 전환하고 조잡함을 잠급니다.


Google이 Dalvik Virtual Machine (본질적으로 HotSpot과 같은 또 다른 Java Virtual Machine)을 AOT 컴파일러 인 Android Run Time (ART)으로 대체하는 방향으로 이동하고 있다는 것을 알았 기 때문에이를 이해하려고 노력했지만 Java는 일반적으로 HotSpot을 사용합니다. , 이는 JIT 컴파일러입니다. 분명히 ARM은 Dalvik보다 약 2 배 빠르기 때문에 "Java가 AOT도 사용하지 않는 이유는 무엇입니까?"라고 생각했습니다. 어쨌든, 내가 모을 수있는 점에서, 주요 차이점은 JIT가 런타임 동안 적응 형 최적화를 사용한다는 것입니다. 예를 들어 자주 실행되는 바이트 코드 부분 만 네이티브 코드로 컴파일 할 수 있습니다. 반면 AOT는 전체 소스 코드를 네이티브 코드로 컴파일하고 적은 양의 코드가 더 많은 양의 코드보다 빠르게 실행됩니다.
대부분의 Android 앱이 소량의 코드로 구성되어 있으므로 평균적으로 전체 소스 코드를 네이티브 코드 AOT로 컴파일하고 해석 / 최적화와 관련된 오버 헤드를 피하는 것이 더 합리적이라고 생각해야합니다.


여기에 나열되지 않은 JIT의 장점 중 하나는 별도의 어셈블리 / dll / jar에 걸쳐 인라인 / 최적화 할 수 있다는 것입니다 (단순함을 위해 여기서부터 "어셈블리"를 사용하겠습니다).

If your application references assemblies which might change after install (e. g. pre-installed libraries, framework libraries, plugins), then a "compile-on-install" model must refrain from inlining methods across assembly boundaries. Otherwise, when the referenced assembly is updated we would have to find all such inlined bits of code in referencing assemblies on the system and replace them with the updated code.

In a JIT model, we can freely inline across assemblies because we only care about generating valid machine code for a single run during which the underlying code isn't changing.


It seems that this idea has been implemented in Dart language:

https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

JIT compilation is used during development, using a compiler that is especially fast. Then, when an app is ready for release, it is compiled AOT. Consequently, with the help of advanced tooling and compilers, Dart can deliver the best of both worlds: extremely fast development cycles, and fast execution and startup times.


Maybe it has to do with the modern approach to programming. You know, many years ago you would write your program on a sheet of paper, some other people would transform it into a stack of punched cards and feed into THE computer, and tomorrow morning you would get a crash dump on a roll of paper weighing half a pound. All that forced you to think a lot before writing the first line of code.

Those days are long gone. When using a scripting language such as PHP or JavaScript, you can test any change immediately. That's not the case with Java, though appservers give you hot deployment. So it is just very handy that Java programs can be compiled fast, as bytecode compilers are pretty straightforward.

But, there is no such thing as JIT-only languages. Ahead-of-time compilers have been available for Java for quite some time, and more recently Mono introduced it to CLR. In fact, MonoTouch is possible at all because of AOT compilation, as non-native apps are prohibited in Apple's app store.


The difference between platform-browser-dynamic and platform-browser is the way your angular app will be compiled. Using the dynamic platform makes angular sending the Just-in-Time compiler to the front-end as well as your application. Which means your application is being compiled on client-side. On the other hand, using platform-browser leads to an Ahead-of-Time pre-compiled version of your application being sent to the browser. Which usually means a significantly smaller package being sent to the browser. The angular2-documentation for bootstrapping at https://angular.io/docs/ts/latest/guide/ngmodule.html#!#bootstrap explains it in more detail.

참고URL : https://stackoverflow.com/questions/2106380/what-are-the-advantages-of-just-in-time-compilation-versus-ahead-of-time-compila

반응형