JIT 컴파일이란?
- JIT Compile 은 Just-In-Time compile (알맞은 때에 컴파일) 의 약자이다.
- 소스 코드를 미리 기계 코드로 변환하는 기존 컴파일러 (AOT) 와 달리 런타임에 네이티브 코드를 생성한다.
- 처음엔 바이트코드 형식으로 해석되거나 실행되지만 자주 실행되는 부분은 속도를 위해 동적으로 기계 코드로 컴파일된다.
- 자주 실행되는 부분을 저장소에 저장해놓는 것을 Optimization 이라고 표현한다.
- Optimization 된 부분이 다시 자주 사용하지 않게 되면 Deoptimization 을 다시 거친다.
JIT 은 어떻게 탄생되었는가?
- 개념 자체는 새로운 것이 아니며, 1980년대에 Smalltalk 이 시초가 됐다.
- Smalltalk 의 설계자들이 해석된 언어를 보다 효율적으로 만들기 위해 JIT 기술을 구현했다.
V8 에서 JIT 의 동작 방식
파싱 및 초기 컴파일
- V8 은 소스 코드를 파싱하며 문법 오류를 확인
- 바이트 코드라는 중간 표현으로 컴파일함
- V8의 인터프리터인 Ignition 이 수행
- 바이트 코드는 기계가 이해하기 쉽지만 머신 코드만큼 최적화되지 않은 코드임
런타임 프로파일링
- 바이트 코드가 실행되면 V8은 백그라운드에서 프로파일링 데이터를 수집
- 데이터에는 함수 호출 빈도, 변수 유형, 코드의 어느 부분이 자주 실행되는지(핫스팟) 에 대한 정보가 포함됨
핫 함수 식별 (Identify Hot functions)
- 자주 실행되는 함수를 핫 함수(Hot Functions) 로 식별함
- JIT 컴파일 시 최적화에 중요한 역할을 함
계층화된 컴파일 접근 사용 (Tiered Compilation Approach)
- V8은 2개의 컴파일러를 사용함
- 인터프리터로서 Ignition 을 사용
- 최적화 컴파일러로서 TurboFan 을 사용
- 처음에는 Ignition 이 빠른 실행을 위해 모든 코드를 바이트 코드로 컴파일
- 이후 특정 함수가 "핫 함수" 로 식별되면, TurboFan 이 해당 함수를 고도로 최적화된 기계어 코드로 컴파일
최적화 (Optimization)
- TurboFan 은 "핫 함수" 외에도 프로파일러가 수집한 정보를 이용하여 함수 인라이닝, 중복 코드 제거, 루프 최적화 등 정보에 입각한 결정을 내림
필요한 경우 최적화 해제 (Deoptimization)
- 최적화 단계에서 설정한 가정이 런타임에 적용되지 않으면, V8은 코드 최적화를 해제할 수 있음
- 최적화 해제 시 V8 은 최적화된 기계어 코드를 덜 최적화된 바이트 코드로 되돌리거나 업데이트된 가정을 사용하여 다시 최적화 할 수도 있음
최적화된 코드 실행
- 코드가 최적화되어 머신 코드로 컴파일되면 실행됨
- 최적화된 코드는 원래 바이트코드보다 훨신 빠르게 실행됨
지속적인 모니터링 및 최적화
- V8은 실행 중인 코드를 지속적으로 모니터링하여 프로그램의 실행 패턴이 변경되면 추가로 최적화하거나 최적화를 해제함
정리
- JIT 컴파일 프로세스를 통해 V8은 초기 바이트코드 컴파일 덕에 자바스크립트 실행을 일단 빠르게 하고 필요에 따라 코드를 최적화해 시작 시간과 런타임 성능 간의 균형을 맞출 수 있음
- 이러한 동적이고 적응적인 접근 방식은 웹 앱에서 발생하는 다양하고 변화무쌍한 워크로드에 적합함
사용되는 곳
자바
- JVM 은 JIT 컴파일을 사용하여 바이트 코드를 네이티브 머신 코드로 변환
V8, JavaScriptCore
- 최신 브라우저의 Javascript 엔진은 더 빠른 웹 성능을 위해 JIT 컴파일을 사용
반응형
'컴파일' 카테고리의 다른 글
AOT (Ahead-Of-Time) 컴파일이란? (0) | 2023.10.07 |
---|