14

私は次のように機能するBrainfuck実装(C ++)を作成しました:

  1. 入力brainfuckファイルを読む
  2. 些細な最適化を行う
  3. brainfuckをVMのマシンコードに変換します
  4. このマシンコードをVMで実行します

これはかなり高速ですが、ボトルネックは現在VMにあります。これはC++で記述されており、トークンを読み取り、アクションを実行します(Brainfuckを知っている場合は、それほど多くはありません)。

私がやりたいのは、VMを取り除き、その場でネイティブマシンコードを生成することです(基本的にはJITコンパイラー)。これは簡単に20倍のスピードアップになります。

これは、ステップ3がJITコンパイラに置き換えられ、ステップ4が生成されたマシンコードの実行に置き換えられることを意味します。

どこから始めればよいのかわからないので、いくつか質問があります。

  1. これはどのように機能し、生成されたマシンコードはどのように実行されますか?
  2. ネイティブマシンコードを生成するためのC++ライブラリはありますか?
4

4 に答える 4

17
  1. 生成されたマシンコードは、通常の関数としてjmp-edまたは-edされます。call場合によっては、生成されたコードを含むメモリの実行なしフラグ(NXビット)を無効にする必要もありました。Linuxでは、これはmprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC.)Windowsで行われ、NXはDEPと呼ばれます。

  2. いくつかあります...例:http: //www.gnu.org/software/lightning/-GNU Lightning(ユニバーサル)およびhttps://developer.mozilla.org/En/Nanojit-FirefoxJavaScriptで使用されるNanojit JITエンジン。より強力で最新のJITはLLVMです。BFコードをLLVMIRに変換するだけで、LLVMは多くのプラットフォームの最適化とコード生成を実行したり、JIT機能を備えたインタープリター(仮想マシン)でLLVMIRを実行したりできます。BF用の完全なLLVMJITコンパイラを備えたBFとLLVMに関する投稿がありますhttp://www.remcobloemen.nl/2010/02/brainfuck-using-llvm/

別のBF+LLVMコンパイラーは、LLVMのsvnにあります:https ://llvm.org/svn/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp

于 2011-05-13T01:49:32.093 に答える
6

LLVMは、中間形式からネイティブコードを生成するための完全なC ++ライブラリ(またはライブラリのセット)であり、ドキュメントと例を備えており、JITterの作成に使用されています。

(フレームワークを使用するC / C ++コンパイラもありますが、フレームワーク自体は他の言語にも使用できます)。

于 2011-05-13T01:52:25.883 に答える
4

これは遅いかもしれませんが、他の人の助けのために私はこの答えを投稿しています。

JITコンパイラには、AOTコンパイラが持つすべてのステップがあります。主な違いは、AOTコンパイラがexeなどの実行可能ファイルにマシン依存コードを出力するのに対し、JITコンパイラは実行時にマシン依存コードをメモリにロードすることです(したがって、再コンパイルとロードが必要になるたびにパフォーマンスのオーバーヘッドが発生します)。

JITコンパイラは実行時にどのようにマシンコードをメモリにロードしますか?

私はあなたがすでにそれについて知っていると思うので、私はあなたに機械語について教えません、

たとえば。アセンブリコード

mov    rax,0x1

に翻訳されます

48 c7 c0 01 00 00 00

翻訳されたコードを動的に生成し、次のようなベクトルに保存します(これはCベクトルです)

vector machineCode{
   0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 
}

次に、このベクトルをメモリにコピーします。このため、このコードに必要なメモリサイズを知る必要があります。これは、machinecode.size()で取得でき、ページサイズを覚えておいてください。

このベクトルをメモリにコピーするには、Cでmmap関数を呼び出す必要があります。ポインタをコードの先頭に設定して呼び出します。あなたは行ってもいいです。

不明な点がある場合は申し訳ありませんが、簡単にするためにこの投稿をいつでもチェックでき ますhttps://solarianprogrammer.com/2018/01/10/writing-minimal-x86-64-jit-compiler-cpp/ https:// github .com / spencertipping / jit-tutorial

于 2018-08-14T10:34:42.703 に答える
3

GNU Lightningは、いくつかの異なるアーキテクチャのネイティブコードを生成できるマクロのセットです。ステップ3では、Lightningマクロを使用して、後で実行するバッファーにマシンコードを直接出力する必要があるため、アセンブリコードをしっかりと理解する必要があります。

于 2011-05-13T01:49:15.047 に答える