知識ベース

動的再コンパイル

コンピューターサイエンスでは、 動的再コンパイルdynarecまたは疑似頭字語DRCと略されることもあります)は、一部のエミュレーターと仮想マシンの機能であり、システムは実行中にプログラムの一部を再コンパイルする場合があります。実行中にコンパイルすることにより、システムは生成されたコードを調整してプログラムのランタイム環境を反映し、従来の静的コンパイラでは利用できない情報を活用してより効率的なコードを生成できる可能性があります。

用途

ほとんどの動的リコンパイラは、実行時にアーキテクチャ間でマシンコードを変換するために使用されます。これは、レガシーゲームプラットフォームのエミュレーションでしばしば必要とされるタスクです。その他の場合、システムは、Javaまたは.NET共通言語ランタイムのバイトコードなどの移植可能なプログラム表現を実行するために、適応最適化戦略の一部として動的再コンパイルを採用する場合があります。また、フルスピードデバッガーは、動的再コンパイルを利用して、ほとんどの最適化解除手法で発生するスペースオーバーヘッドや、動的スレッド移行などの他の機能を削減します。

タスク

動的再コンパイラが実行する必要がある主なタスクは次のとおりです。

  • ソースプラットフォームからマシンコードを読み込む
  • ターゲットプラットフォーム用のマシンコードの発行

動的再コンパイラは、いくつかの補助的なタスクを実行することもあります。

  • 再コンパイルされたコードのキャッシュの管理
  • サイクルカウントレジスタを備えたプラットフォームでの経過サイクルカウントの更新
  • 割り込みチェックの管理
  • GPUなどの仮想化されたサポートハードウェアへのインターフェイスの提供
  • 高レベルのコード構造を最適化して、ターゲットハードウェアで効率的に実行する(以下を参照)

プログラムがエミュレーターで実行されており、ヌル終了ストリングをコピーする必要があるとします。プログラムはもともと非常に単純なプロセッサ用にコンパイルされています。このプロセッサは一度に1バイトしかコピーできません。コピーするには、まずソース文字列からレジスタに読み込み、次にそのレジスタから宛先文字列に書き込む必要があります。元のプログラムは次のようになります。

最初:mov A、;ソース文字列の最初の文字の位置を入力します。レジスタA mov B 、;宛先文字列の最初の文字の位置を入力します。レジスタBループ内:mov C、;レジスタAのアドレスにあるバイトをレジスタC mov、Cにコピーします。レジスタCのバイトをレジスタB inc Aのアドレスにコピーします。指すようにレジスタAのアドレスをインクリメントします。次のバイトinc B;指すようにレジスタBのアドレスをインクリメントします。次のバイトcmp C、#0;コピーしたばかりのデータを0(ストリングエンドマーカー)jnzループと比較します。 0でない場合は、さらにコピーする必要があるので、戻ってください。そして次のバイトエンドをコピーします:;ループしなかった場合は、終了している必要があります。だから他のことを続けてください。

エミュレータは同様のプロセッサで実行されている可能性がありますが、文字列のコピーが非常に優れており、エミュレータはこれを利用できることを知っています。命令の文字列コピーシーケンスを認識し、実行の直前にそれらをより効率的に書き換えて、エミュレーションを高速化することを決定する場合があります。

movsと呼ばれる新しいプロセッサに命令があり、特に文字列を効率的にコピーするように設計されているとします。私たちの理論的なmovs命令は、16バイトを一度にコピーします。中間のレジスタCにロードする必要はありませんが、0バイト(文字列の終わりを示す)をコピーしてゼロフラグを設定すると停止します。また、文字列のアドレスがレジスタAおよびBにあることを認識しているため、実行するたびにAおよびBを16インクリメントし、次のコピーの準備ができます。

新しい再コンパイルされたコードは次のようになります。

最初:mov A、;ソース文字列の最初の文字の位置を入力します。レジスタA mov B 、;宛先文字列の最初の文字の位置を入力します。レジスタBループ内:movs、;レジスタAのアドレスの16バイトをアドレスにコピーします。レジスタBで、16 jnzループでAとBをインクリメントします。ゼロフラグが設定されていない場合、到達していません。文字列の終わりなので、戻ってもう少しコピーします。終わり: ;ループしなかった場合は、終了している必要があります。だから他のことを続けてください。

プロセッサが同じタスクを実行するためにそれほど多くの命令をロードする必要がないという理由だけでなく、movs命令がプロセッサ設計者によって最適化される可能性があるため、即時の速度の利点があります最初の例。たとえば、プロセッサでの並列実行を活用して、バイトをコピーしている間にAとBをインクリメントできます。

用途

一般的用途

  • 多くのJava仮想マシンは、動的再コンパイルを備えています。
  • AppleのMac OS X for x86用Rosettaを使用すると、PowerPCコードをx86アーキテクチャで実行できます。
  • PowerPCハードウェアで680x0コードを実行するために、従来のMac OSで使用されていた新しいバージョンのMac 68Kエミュレーター。
  • Psyco、Python専用のコンパイラ。
  • 透過的なバイナリダイナミックオプティマイザーの例であるHP Dynamoプロジェクト。
  • DynamoRIOは、ARM、x86-64、およびIA-64(Itanium)命令セットで動作するDynamoのオープンソースの後継製品です。
  • Vx32仮想マシンは、動的な再コンパイルを使用して、安全なアプリケーションプラグイン用のOSに依存しないx86アーキテクチャサンドボックスを作成します。
  • PowerPCでx86コードを実行するために使用されるMicrosoft Virtual PC for Mac。
  • QEMU、オープンソースのフルシステムエミュレーター。
  • FreeKEYB、多くの使いやすさを強化した国際的なDOSキーボードおよびコンソールドライバーは、ユーザー設定(選択した機能、言語、レイアウト)および実際のランタイム環境(OSバリアント)に基づいて、自己変更コードおよび動的なデッドコード除去を使用して、メモリ内イメージを最小化しましたおよびバージョン、ロードされたドライバー、基盤となるハードウェア)、依存関係の自動解決、バイトレベルの粒度でのコードセクションの動的な再配置と再結合、ソースコードで提供されるセマンティック情報に基づいたopstringの最適化、アセンブリ中に特別なツールによって生成された再配置情報および取得されたプロファイル情報ロード時に。
  • OVPsim、無料で入手可能なフルシステムエミュレーター。
  • VirtualBoxは動的再コンパイルを使用します。
  • メモリのデバッグ、メモリリークの検出、およびプロファイリングのためのプログラミングツールであるValgrindは、動的再コンパイルを使用します。

ゲーミング

  • MAMEは、MIPS、SuperH、PowerPC、さらにはVoodooグラフィック処理ユニットのCPUエミュレーターで動的再コンパイルを使用します。
  • 1964年、x86ハードウェア用のNintendo 64エミュレーター。
  • Wii64、Wii用のニンテンドー64エミュレーター。
  • WiiSX、任天堂Wii用のSony PlayStationエミュレーター。
  • Mupen64Plus、マルチプラットフォームのNintendo 64エミュレーター。
  • Yabause、マルチプラットフォームのSaturnエミュレーター。
  • Xbox 360の後方互換性機能(つまり、元のXbox用に作成されたゲームの実行)は、動的な再コンパイルを使用すると広く想定されています。
  • PPSSPP、Sony PlayStation Portableエミュレーター。 x86とARMの両方のリコンパイラ。
  • PSEmu Pro、Sony PlayStationエミュレーター。
  • Ultrahleは、商用ゲームを完全に実行する最初のNintendo 64エミュレーターです。
  • Sony PlayStation 2エミュレーターであるPCSX2には、「SuperVU」の後継である「microVU」と呼ばれるリコンパイラーがあります。
  • ニンテンドーゲームキューブおよびWiiエミュレーターであるDolphinには、dynarecオプションがあります。
  • GCemu、任天堂のGameCubeエミュレーター。
  • NullDC、x86用のセガドリームキャストエミュレーター。
  • MSX用の任天堂ゲームボーイエミュレーターであるGEMは、最適化動的リコンパイラーを使用します。
  • ニンテンドーDSエミュレーターであるDeSmuMEには、dynarecオプションがあります。
  • Sony PlayStation PortableエミュレーターであるSoywizのPspには、dynarecオプションがあります。
  • RPCS3、Sony PlayStation 3エミュレーター。 x86-64のCell ProcessorでPPUとSPUの両方をリコンパイラー
  • Wif UエミュレーターであるDecaf-emuは、libbinrecライブラリーを使用してPowerPC32からx86_64コードハードウェアへの動的再コンパイル(JIT)を使用します(ライブラリー自体は任意のハードウェアアーキテクチャで実行できます)。