web-dev-qa-db-ja.com

C、C ++などのJITコンパイラ

CやC++などのコンパイル済み言語用のジャストインタイムコンパイラーはありますか? (頭に浮かぶ最初の名前はClangとLLVMです!しかし、現在それらがサポートしているとは思いません。)

説明:

ソフトウェアは、CやC++のようにコンパイルしてマシン言語に変換する場合でも、ランタイムプロファイリングフィードバックと実行時のホットスポットの積極的に最適化された再コンパイルの恩恵を受けることができると思います。

プロファイルに基づく最適化も同様の働きをしますが、JITは異なる環境でより柔軟になります。 PGOでは、リリースする前にバイナリを実行します。リリースした後は、実行時に収集された環境/入力フィードバックを使用しません。したがって、入力パターンが変更された場合は、パフォーマンスペナルティの調査になります。しかし、JITはそのような状況でもうまく機能します。

ただし、JITコンパイルのパフォーマンス上の利点がそれ自体のオーバーヘッドを上回るかどうかは、議論の余地があると思います。

33

[現在は基本的に廃止されているまったく異なる回答については、編集履歴を参照してください。]

はい、CやC++用のJITコンパイラがいくつかあります。

CLing (ゲームから推測できるかもしれませんが)はClang/LLVMに基づいています。通訳のように振る舞います。つまり、ソースコードをいくつか与え、実行するコマンドを与えると、実行されます。ここでは、最大限の最適化ではなく、主に利便性と高速コンパイルに重点を置いています。したがって、技術的には質問自体への回答ですが、これは実際にはOPの意図にあまり適していません。

別の可能性は NativeJIT です。これは、質問に多少異なります。特に、CまたはC++のソースコードを受け入れず、コンパイルして実行します。むしろ、C++プログラムにコンパイルできる小さなコンパイラです。これは、基本的にC++プログラム内でEDSLとして表現される式を受け入れ、そこから実際のマシンコードを生成して実行できます。これは、ほとんどのプログラムを通常のコンパイラーでコンパイルできるフレームワークに非常によく適合しますが、実行時までわからないいくつかの式があり、最適な実行速度に近いもので実行する必要があります。

元の質問の明らかな意図については、私の元の答えの基本的な点はまだ残っていると思います:JITコンパイラcanある実行から次の実行まで変化するデータなどに適応します単一の実行中に動的に変化するので、実際には、これは少なくとも一般的なルールとしてはほとんど違いがありません。ほとんどの場合、実行時にコンパイラーを実行することは、かなりの最適化を控える必要があることを意味します。そのため、通常期待する最高のことは、従来のコンパイラーが生成する速度に近いことです。

JITコンパイラーが利用できる情報couldにより、従来のコンパイラーよりも実質的に優れたコードを生成できる状況を想定することは可能ですが、実際に発生するこの例はかなり珍しいようです(そしてほとんどの場合私はそれが起こっていることを確認することができました、それは本当に静的コンパイルモデルではなく、ソースコードの問題が原因でした)。

33
Jerry Coffin

はい、C++用のJITコンパイラがあります。純粋なパフォーマンスの観点からは、プロファイルガイド付き最適化(PGO)が依然として優れていると思います。

ただし、JITコンパイルが実際にまだ使用されていないという意味ではありません。たとえば、Appleは、LLVMをOpenGLパイプラインのJITとして使用します。これは、実行時に非常に多くの情報があり、多くのデッドコードを削除するために使用できるドメインです。

JITのもう1つの興味深いアプリケーションは、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のコードを開発しています。

11
Philipp Claßen

C++/CLIはjittedです。確かに、C++/CLIはC++ではありませんが、かなり近いです。とはいえ、MicrosoftのJITは、少なくとも私の知る限りでは、あなたが求めている非常に賢い/かわいい種類のランタイム動作ベースの最適化を行いません。だからこれは本当に役に立たない。

http://nestedvm.ibex.org/ はMIPSをJavaバイトコードに変換します。これはその後jittedになります。この質問のこのアプローチの問題は、捨てることです。 JITに到達するまでに役立つ情報がたくさんあります。

7
Logan Capaldo

まず、メソッドjitではなくトレースjitが必要だと思います。

最善のアプローチは、ネイティブの実行可能ファイルを作成する前に、コードをllvm IRにコンパイルしてから、トレースコードを追加することです。コードブロックが十分に使用され、変数のvalues(動的言語のような型ではない)に関する十分な情報が収集されたら、コードを(IRから)ガードベースで再コンパイルできます。変数の値について。

Libclangという名前でclangでc/c ++ jitを作成するのにある程度の進歩があったことを覚えているようです。

2
dan_waterworth