スタックベースの仮想マシンを使用する場合と比較して、レジスタベースの仮想マシンを使用する場合の長所と短所は正確には何ですか?
私には、レジスタベースのマシンの方がプログラミングが簡単で効率的であるように思えます。では、JVM、CLR、およびPython VMがすべてスタックベースであるのはなぜですか?
これは、Parrot VMのFAQおよび関連ドキュメントですでにある程度回答されています。 A Parrotの概要 このドキュメントの関連テキストは次のとおりです。
parrot VMには、スタックアーキテクチャではなく、レジスタアーキテクチャがあります。また、PerlやPythonなどの中レベルの演算よりもJavaによく似た、非常に低レベルの操作も行われます。
この決定の理由は主に、基盤となるハードウェアにある程度類似することにより、Parrotバイトコードを効率的なネイティブマシン言語にコンパイルできることです。
さらに、高水準言語の多くのプログラムは、ネストされた関数とメソッドの呼び出しで構成されており、中間結果を保持するための字句変数が含まれる場合もあります。非JIT設定では、スタックベースのVMがポップして同じオペランドを何度もプッシュしますが、レジスタベースのVMは、適切な量のレジスタを割り当て、それらを操作することで、操作量とCPU時間を大幅に削減できます。
これを読むこともできます: レジスタ対インタープリタ設計のスタック 少し引用します:
本当の疑いはありません。スタックマシン用のコードを生成する方が簡単です。ほとんどの新入生コンパイラの学生はそれを行うことができます。アキュムレータを備えたスタックマシンとして扱う場合を除いて、レジスタマシンのコード生成は少し難しいです。 (これは実行可能ですが、パフォーマンスの観点からは理想的ではありませんが)ターゲットを絞ることの単純さはそれほど大きな問題ではありません。少なくとも、私にとってはそうではありません。実際に直接ターゲットとする人が少ないためです。つまり、さあ、あなたが実際に誰かが気にかけるであろう何かのためにコンパイラを書こうとする人を何人知っていますか?数は少ないです。もう1つの問題は、コンパイラーの知識を持っている人の多くが、レジスターマシンをターゲットに設定することに慣れているということです。
ハードウェアに実装されたレジスタベースのマシンは、低速のRAMへのアクセスが少ないため、より効率的になります。ただし、ソフトウェアでは、レジスタベースのアーキテクチャでも、RAMに「レジスタ」が存在する可能性があります。その場合、スタックベースのマシンも同様に効率的になります。
さらに、スタックベースのVMを使用すると、コンパイラを簡単に作成できます。レジスタ割り当て戦略を処理する必要はありません。基本的に、無制限の数のレジスタがあります。一緒に働きます。
更新:解釈されたVMを想定してこの回答を書きました。 JITコンパイル済みVMには当てはまらない場合があります。私は この論文 に出くわしました。これは、JITコンパイル済みVMがレジスタアーキテクチャを使用するとより効率的になる可能性があることを示しているようです。
従来、「VM実装」の単純さにより、コンパイラバックエンドを簡単に作成できるため、仮想マシンの実装者はレジスタベースよりもスタックベースのアーキテクチャを好んでいます。スタックアーキテクチャの言語とコードの密度および実行可能ファイルは、レジスタアーキテクチャの実行可能ファイルよりも常に小さく、単純さとコード密度はパフォーマンスを犠牲にします。
調査によると、登録ベースのアーキテクチャでは、スタックベースのアーキテクチャよりも平均47%少ない実行VM命令が必要であり、レジスタコードは対応するスタックコードより25%大きいですが、これによりコストが増加します。より多くのフェッチのVMコードサイズが大きいための命令は、VM命令あたり無視できるわずか1.07%の実マシン負荷を含みます。レジスタの全体的なパフォーマンスbased VMは、標準的なベンチマークを実行するために平均して32.3%短い時間で済みます。
スタックベースのVMを構築する理由の1つは、実際のVMオペコードを小さく簡単にすることができることです(オペランドをエンコード/デコードする必要がないため)。これにより、生成されるコードが小さくなり、= VMコードがシンプルになります。
レジスターはいくつ必要ですか?
私はおそらくそれ以上の数が必要になるでしょう。
スタックベースのVMはより単純で、コードははるかにコンパクトです。現実の例として、友人が(約30年前に)自作のForth VMを使用してデータロギングシステムを構築しました。ForthVMは30 バイト 2kのマシン上のコードROMおよび256バイトのRAM。
「レジスターベース」の仮想マシンが「プログラムをより簡単に」または「より効率的に」なることは私には明らかではありません。おそらく、JITコンパイルフェーズ中に仮想レジスタがショートカットを提供すると考えているのでしょうか?実際のプロセッサにはVMよりも多いまたは少ないレジスタがあり、それらのレジスタはさまざまな方法で使用される可能性があるため、これは確かに当てはまりません。 (例:減分される値は、x86プロセッサーのECXレジスターに配置するのが最適です。)実際のマシンにVMよりも多くのレジスターがある場合、リソースを浪費しており、「レジスター」を使用しても何も得られません。ベースの」プログラミング。
スタックベースのVMは、コードを生成する方が簡単です。
レジスタベースのVMは、高速実装の作成と、高度に最適化されたコードの生成が容易です。
最初の試みとして、スタックベースのVMから始めることをお勧めします。