3

多くの人が一見するとすぐに「Java」と叫ぶかもしれないことを私は知っていますが、いいえ、私はJavaの品質を知っています。最初に私の質問を詳しく説明させてください。

通常、Windows、Mac OS X、Linuxのいずれであっても、システム上でプログラムをネイティブの速度で実行する場合は、ソースコードからコンパイルする必要があります。システム内の別のシステムのプログラムを実行する場合は、仮想マシンまたはエミュレーターを使用する必要があります。これらのツールを使用すると、非ネイティブOSで必要なプログラムを使用できますが、パフォーマンスや不具合の問題が発生する場合があります。

また、「JITコンパイラ」と呼ばれる新しいコンパイラがあり、コンパイラは実行前にバイトコードプログラムをネイティブの機械語に解析します。JITコンパイラを使用すると、パフォーマンスが大幅に向上する可能性がありますが、それでも、パフォーマンスはネイティブシステムで実行した場合と同じではありません。

Linux上の別のプログラムであるWINEも、LinuxシステムでWindowsプログラムを実行するための優れたツールです。その上でTeamFortress2を実行してみて、いくつかの設定を試してみました。Windowsでは1280x1024の中高設定で最大40fpsを取得しました。Linuxでは、最大40 fpsを取得するには、すべてを1280x1024で低くする必要があります。ただし、注目すべき点が2つあります。

  1. ポリゴンモデルの設定は、低く設定しても高く設定しても、フレームレートに影響を与えないようです。
  2. 現在のフレームの描画されたピクセルの操作を必要とする後処理効果またはいくつかの特殊効果がある場合、フレームレートは10〜20fpsに低下します。

この時点から、通常のポリゴンレンダリングは問題ないことがわかりますが、ジョブにグラフィックカードを必要とする新しいレンダリング方法になると、クロールが遅くなります。

とにかく、この質問はかなり理論的です。何かできることはありますか?WINEはSTEAMとTeamFortress2を実行できることがわかります。欠陥はありますが、より低い設定で実行できます。あるいは、「ソースから再コンパイルせずに、システム上のプログラム全体を別のシステムに変換して、ネイティブの速度を得ることができるか」という質問もする必要があります。AOTコンパイラもあるので、何かに使用することはできますか。このような?または、ネイティブ速度で実行されるシステムプログラムにネイティブではなく、完璧なものを作成することを不可能にする非常に多くの制約(DirectX呼び出しやソフトウェアアーキテクチャの違いなど)がありますか?

4

2 に答える 2

6

複数のシステムで同じコンパイル済みコード本体を再コンパイルせずにネイティブ速度で実行するための最初のステップは、1つのプロセッサ命令セットを選択し、他のすべてのシステムを破棄することです。Intelを選択した場合、あるアーキテクチャのネイティブマシンコード命令は他のプロセッサには完全に理解できないため、ARM、MIPS、PowerPCなどを破棄する必要があります。

Ok。したがって、ここでのタスクは、コンパイルされたネイティブコードの同じ本体を、再コンパイルせずにネイティブ速度で複数のシステム(すべて同じプロセッサアーキテクチャを使用)で実行することです。したがって、基本的には、同じハードウェア上の異なるオペレーティングシステムで同じコードを実行する必要があります。

ハードウェアが同じで、唯一の違いがオペレーティングシステムである場合、簡単な答えは「はい」です。オペレーティングシステムを呼び出さずにコードを記述できれば、それを実行できます。メモリ割り当てはありません。コンソール出力はありません。ファイルI/Oはありません。ネットワークI/Oはありません。楽しくない。

さらに、オペレーティングシステムごとに再配置可能なコードを表す方法が異なるため、コードはアドレス再配置の修正を必要としないように記述する必要があります。これを行う1つの方法は、書き込み可能なデータ(グローバル変数、スタック、およびヒープ)に使用するスペースを予約するなど、メモリに表示されるのとまったく同じようにコードをディスクに配置することです。次に、コードを実行するために必要なのは、ファイルバイトを事前定義されたベースアドレスのメモリにコピーし、開始アドレスにジャンプすることだけです。

MSDOS .com実行可能ファイル形式は、少なくとも1981年以来これを行っており、CP/Mはそれよりずっと前から行われています。

しかし、MSDOSには、当時と戦うための今日のウイルススキャナーがありませんでした。ホストOS以外の誰かがファイルデータをメモリにロードし、そのメモリを実行しようとすると、ウイルススキャナーは非常に興奮します。なぜなら、それはまさにウイルスが行うことだからです。

各OSには独自の実行可能ファイル形式があるため、これらすべての異なるオペレーティングシステムで「完璧な」ネイティブコードのブロックをメモリに取り込む方法も理解する必要があります。ネイティブコードのブロックを実行するオペレーティングシステムごとにコンパイルされたプログラムローダーが少なくとも1つ必要です。ターゲットにするOSごとにプログラムローダーを作成しているときに、独自のファイルI/を定義することもできます。ネイティブコードのブロックが任意のシステムでファイルI/Oを実行できるように、OSネイティブの同等のものにマップするO関数。コンソールI/Oまたはグラフィックス出力についても同様です。

ちょっと待ってください-それはまさにWINEが行うことです。

これが、WINEに表示されるフレームレートがホストOSでの同じ操作よりもはるかに低い理由でもあります-WINEはWin32 GDIグラフィックス呼び出しをネイティブホストOS(Linux-> XWindows)によって提供されるものに変換しています。関数が完全に一致する場合、または操作のセマンティックの不一致がある場合(これはよくあることです)、WINEはすべての機能自体を実装する必要があり、場合によっては多大なコストがかかります。

しかし、IDEドライブ、USBデバイス、BIOS機能などの標準化されたハードウェアが広く普及していることを考えると、OSに組み込まれているものに独自のポータブルAPIをマッピングするという面倒な作業をすべて行う必要はないかもしれません。 IDEデバイスへのファイルI/Oを実行し、VESABIOS機能を使用してグラフィック出力を実行します。コードを少し抽象化すると、複数の種類のハードウェアをサポートし、実行時に見つかったハードウェアに基づいて、使用する適切な関数ポインターを選択できます。

そうすれば、再コンパイルせずに、ネイティブコードのブロックを(特定のプロセッサアーキテクチャを使用して)任意のシステムでネイティブ速度で実行できます。

ちょっと待ってください-あなたはあなた自身のOSを書いただけです。;>

于 2011-01-09T08:39:31.603 に答える
4

はい、あるプロセッサ アーキテクチャおよびオペレーティング システム用に記述されたバイナリ実行可能プログラムを、別のプロセッサおよびオペレーティング システムで実行されるバイナリ実行可能プログラムに変換することは、技術的に可能です。それはまた、途方もない量の仕事でもあります。

「ネイティブ コードの実行速度」という用語には問題があります。最適化を無効にしてプログラムをネイティブ コードにコンパイルすると、結果のコードは「ネイティブ コードの実行速度」で実行されるネイティブ実行可能コードになりますが、最適化を有効にしてコンパイルされた同じソース コードよりも実行速度が遅くなる可能性があります。どちらも「ネイティブ コード実行速度」を実行していますが、同じコア アルゴリズムを実現するために異なる量と品質のマシン コードを実行しています。

マシン命令は、高レベルのソース プログラミング言語よりもはるかに原始的です。ソース コードをマシン コードにコンパイルすると、多くの情報が失われます。たとえば、データ型は通常、コンパイラによって少数のマシン プリミティブ (ポインター、整数、浮動小数) に縮小されます。文字列はメモリへのポインタです。char は整数です。オブジェクト インスタンスはポインタです。

ある機械語命令セットを別の機械語命令セットに変換する場合、ソース コード コンパイラほどデータに関する情報がないため、不利になります。ソースコードからコンパイルすることで、コンパイラーは、マシンコードだけを見るだけでは発見が非常に困難な、データ内の関係と最適化を確認できます。

ストーリータイム: Digital Equipment Corporation は FX!32 と呼ばれるシステムを作成しました。このシステムは、ネイティブ コンパイルされた Win32 Intel x86 実行可能ファイルを取得して逆コンパイルし、ロジックを Windows NT AXP を実行するネイティブ Alpha AXP プロセッサ命令に変換しました。この場合、OS は少なくとも同じ生地から切り出されましたが、1 つは 32 ビットで、もう 1 つは 64 ビットであり、マシン コード レベルでは根本的に異なる呼び出し規約がありました。それにもかかわらず、それは機能し、非常にうまく機能しました。ハードウェアの違いにより、AXP で実行されている Intel x86 アプリは、最終的に Intel ハードウェアで実行されている同じアプリよりも高速に実行される可能性があります。(FX!32 は、Intel アプリを数回実行した後、プロファイリングを使用して AXP コードを再最適化したため、通常、パフォーマンスは最初はかなり悪くなりましたが、アプリを実行するたびに改善されました)

ただし、すべてがネイティブ AXP 命令を実行していたにもかかわらず、FX!32 変換アプリは、ソース コードを取得して AXP 命令セット専用に再コンパイルするほど速くは実行されませんでした。FX!32 で変換されたネイティブ AXP 命令ストリームは、元の Intel x86 命令のセマンティクスを完全に表現する必要があるため、(目に見えない) より高いレベルのアルゴリズムがそれらのセマンティクスのすべての側面を必要としなかったとしても、大きくなりました。

機械命令から機械命令への翻訳を行う場合、シンフォニーのすべての音符を見たり聞いたりすることができますが、旋律を定義する音符を選択するのに苦労する場合があります。

于 2011-01-09T09:40:25.807 に答える