C, C ++ 등을위한 JIT 컴파일러


33

C 및 C ++와 같은 컴파일 된 언어를위한 적시 컴파일러가 있습니까? (명심해야 할 첫 번째 이름은 Clang과 LLVM입니다! 그러나 현재 지원하지는 않습니다.)

설명:

소프트웨어는 런타임 프로파일 링 피드백과 C 및 C ++와 같은 컴퓨터로 컴파일 된 언어에서도 런타임에 핫스팟을 적극적으로 최적화하여 재 컴파일함으로써 혜택을 얻을 수 있다고 생각합니다.

프로파일 가이드 최적화는 비슷한 작업을 수행하지만 차이점이 있으면 JIT가 다른 환경에서 더 유연 해집니다. PGO에서는 바이너리를 릴리스하기 전에 바이너리를 실행합니다. 릴리스 한 후에는 런타임에 수집 된 환경 / 입력 피드백을 사용하지 않습니다. 따라서 입력 패턴이 변경되면 성능 저하에 대한 프로브입니다. 그러나 JIT는 그러한 조건에서도 잘 작동합니다.

그러나 JIT 컴파일 성능 이점이 자체 오버 헤드보다 더 중요하다는 것은 논쟁의 여지가 있다고 생각합니다.


1
주 제외 오프 사이트 리소스.
DeadMG

1
그것이 질문에 맞는지 확실하지 않지만 유용성을 기대하기 위해 Julia 언어로 Cxx 패키지 를 유용하게 사용합니다 . @ PhilippClaßen 답변에 설명 된 것과 유사한 대화 형 C ++ 프롬프트를 제공합니다.
Antonello

답변:


33

[현재 기본적으로 사용되지 않는 다른 답변에 대해서는 편집 기록을 참조하십시오.]

예, C 및 / 또는 C ++ 용 JIT 컴파일러가 있습니다.

CLing (게임에서 짐작할 수 있듯이)은 Clang / LLVM을 기반으로합니다. 통역사처럼 행동합니다. 즉, 소스 코드를 제공하고 실행할 명령을 실행하면 실행됩니다. 여기서 강조는 최대 최적화가 아니라 편의성 및 빠른 컴파일에 주로 중점을 둡니다. 따라서 기술적으로 질문 자체에 대한 답변이지만 OP의 의도와는 잘 맞지 않습니다.

또 다른 가능성은 NativeJIT 입니다. 이것은 질문에 다소 다르게 적용됩니다. 특히 C 또는 C ++ 소스 코드를 허용하지 않고 컴파일하여 실행합니다. 오히려 C ++ 프로그램으로 컴파일 할 수있는 작은 컴파일러입니다. C ++ 프로그램 내에서 기본적으로 EDSL로 표현되는 표현식을 받아 들여 실제 머신 코드를 생성하여 실행할 수 있습니다. 이것은 일반적인 컴파일러로 대부분의 프로그램을 컴파일 할 수 있지만 런타임까지 알 수없는 몇 가지 표현을 가지고 있으며 최적의 실행 속도에 근접한 것으로 실행하려는 프레임 워크에 훨씬 적합합니다.

원래 질문의 명백한 의도에 관해서는, 나는 원래의 대답의 기본 요점이 여전히 존재한다고 생각합니다 .JIT 컴파일러 한 실행에서 다음 실행까지 다양하거나 단일 실행 동안 동적으로 변하는 데이터와 같은 것들에 적응할 수 있습니다 . 현실은 이것이 적어도 일반적으로 최소한의 차이를 만든다는 것입니다. 대부분의 경우 컴파일러를 런타임에 실행하면 상당히 많은 최적화를 포기해야하므로 일반적으로 기대하는 최선의 방법은 일반적인 컴파일러가 생성하는 속도만큼 빠르다는 것입니다.

JIT 컴파일러 사용할 수있는 정보 가 기존 컴파일러보다 실질적으로 더 나은 코드를 생성 수 있는 상황을 가정 할 수 는 있지만 실제로 이런 경우는 매우 드문 것으로 보입니다 (대부분의 경우 검증 할 수있는 경우) 정적 컴파일 모델이 아닌 소스 코드의 문제로 인해 실제로 발생했습니다.)


1
JIT가 캐시와 같은 파일을 저장하지 않고 모든 것을 처음부터 다시 배우지 않아도되는 이유는 무엇입니까?
JohnMudd

3
@ JohnMudd : 추론이 보안이라고 생각합니다. 예를 들어, 캐시 된 코드를 수정 한 후 다음에 VM을 시작할 때 작성된 코드 대신 내가 넣은 코드를 실행합니다.
Jerry Coffin

4
OTOH, 캐시를 수정할 수 있으면 소스 파일도 수정할 수 있습니다.
user3125367 1

1
@ user3125367 : 예. 그러나 대부분의 경우 컴파일러는 다양한 유형 검사를 수행하며 캐시에서 직접 컴파일 된 코드를로드하는 경우 무시할 수 있습니다. 물론 JIT에 따라-Java는 (컴파일 된) .class 파일을로드 할 때 많은 강제 작업을 수행하지만 다른 많은 작업은 훨씬 적습니다 (대부분의 경우 거의 없음).
Jerry Coffin

11

예, C ++ 용 JIT 컴파일러가 있습니다. 순수한 성능 관점에서 PGO (Profile Guided Optimization)가 여전히 우수하다고 생각합니다.

그러나 이것이 JIT 컴파일이 아직 실제로 사용되지 않았다는 의미는 아닙니다. 예를 들어, Apple은 OpenGL 파이프 라인의 JIT로 LLVM을 사용합니다. 그것은 런타임에 훨씬 더 많은 정보를 가진 도메인으로, 많은 죽은 코드를 제거하는 데 사용될 수 있습니다.

JIT의 또 다른 흥미로운 응용 프로그램은 LLVM 및 Clang을 기반으로하는 대화식 C ++ 인터프리터 인 Cling입니다. https://root.cern.ch/cling

다음은 샘플 세션입니다.

[cling]$ #include <iostream>
[cling]$ std::cout << "Hallo, world!" << std::endl;
Hallo, world!
[cling]$ 3 + 5
(int const) 8
[cling]$ int x = 3; x++
(int) 3
(int const) 3
[cling]$ x
(int) 4

장난감 프로젝트는 아니지만 실제로 CERN에서 Large Hadron Collider의 코드를 개발하는 데 사용됩니다.


7

C ++ / CLI가 불안하다. 부여, C ++ / CLI는 하지 C ++하지만 꽤 가까운 거리에 있습니다. 즉, Microsoft의 JIT는 적어도 내 지식이 아닌 귀하가 요구하는 슈퍼 영리하고 귀여운 종류의 런타임 동작 기반 최적화를 수행하지 않는다고 말했습니다. 따라서 이것은 실제로 도움이되지 않습니다.

http://nestedvm.ibex.org/ 는 MIPS를 Java 바이트 코드로 변환 한 다음이를 지치게합니다. 귀하의 질문에 대한이 접근법의 문제점은 JIT에 도달 할 때까지 유용한 정보를 많이 버린다는 것입니다.


2

먼저, 메소드 jit 대신 추적 jit을 원한다고 가정합니다.

가장 좋은 방법은 코드를 llvm IR로 컴파일 한 다음 기본 실행 파일을 생성하기 전에 추적 코드를 추가하는 것입니다. 코드 블록이 충분히 잘 사용되고 변수 의 (동적 언어와 같은 유형이 아님) 에 대한 충분한 정보 가 수집되면 변수 값을 기반으로 가드를 사용하여 코드를 IR에서 다시 컴파일 할 수 있습니다.

libclang이라는 이름으로 clang에서 ac / c ++ jit을 만드는 과정이 진행된 것을 기억합니다.


1
AFAIK, libclang은 대부분의 clang 기능을 라이브러리로 고려합니다. 따라서 소스 코드를 분석하여 정교한 구문 채색, 보푸라기, 코드 탐색 등을 만들 수 있습니다.
Javier

@Javier, 맞습니다. 라이브러리에 소스 코드의 const char *를 가져 와서 llvm ir를 생성하는 함수가 있다고 생각하지만 지금 생각하면 소스가 아닌 ir를 기반으로하는 것이 좋습니다.
dan_waterworth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.