個人用の仮想マシンを開発しています(もちろんオープンソースです!)
他の仮想マシン、特にスクリプト言語の仮想マシンのソースコードを調査および確認する場合。すべてのVM archsは、私が熟読したロード/ストアアーキテクチャを使用しましたが、VM Arch use register/memory architecture。
ロード/ストアアーチとレジスタ/メモリアーチおよびアドレッシングモードの使用には、パフォーマンス上の利点がありますか?
「レジスタ」を使用するVMなど、さまざまなVMがあります。ただし、VMのポイントは、物理マシンを抽象化することです。そのため、VMは、レジスタの数を制限しない可能性があります!そのようなレジスタは、基本的に同等です。ローカル変数に。
スタックベースのVMは実装が少し簡単で、スタックベースの言語(連結言語)のクラス全体が存在するという点まで、重要な歴史的前例があります。 VMが高水準言語で実装されている場合、スタックエントリのサイズが異なる可能性がある場合(バイトとWordなど)、スタックエントリの型が不明であるため、実際に問題が発生する可能性があります。例: JVM命令は入力され、VMはバイトコードのロード中に、バイトコードがスタックを破損しないことを静的に検証できます。
中間言語が静的単一割り当てフォーム(SSA)で指定されている場合、レジスターベースのVMは最適化により少し簡単な時間を持つことができます。各論理レジスタは1つの命令で割り当てられ、その後は読み取り専用になります。これにより、データフローの分析が容易になります。もちろん、これは論理レジスタから物理レジスタへの単純なマッピングを防ぎますが、スタックベースのVMに比べて不利ではありません。ただし、ほとんどのインタープリターまたはJITコンパイラーは、最適化可能性にあまり関心がありません。
最もよく知られているレジスタベースのVMはLLVMであり、SSAを使用します。これは、VMが前に抽象命令セット(中間表現)として主に使用されます) -clangやrustcなどの-timeコンパイラ。
レジスタベースのVMも動的言語のランタイムに時々ポップアップしますが、ここではよりニッチです。 ParrotとMoarVM(どちらもPerl6言語に接続されている)が思い浮かびます。
仮想マシンのコードは解釈されず、実行時に実際のマシンのマシンコードにコンパイルされるという考え方です。
レジスタ/メモリアプローチでは、ネイティブコードへの変換が難しくなります。データを格納できる場所は2つあります。メモリ内またはレジスタ内ですが、ロード/ストアアーキテクチャにはメモリしかありません。この2つの場所では、分析して優れたネイティブコードに変換することが難しくなっています。
PS。 JITコンパイルは大規模速度を向上させます。レジスタベースのVMは、解釈するときに少し向上するかもしれませんが、JITが目標であるため、それだけの価値はありません。どのようにVMレジスタを実装するかインタプリタで?ほとんどの場合、とにかくそれらをメモリに格納することになります。