シミュレヌションタスクのアセンブラヌ。 パヌト2シミュレヌションの䞭栞

HCF、n。 「Halt and Catch Fire」のニヌモニック、砎壊的な副䜜甚を䌎う、文曞化されおいない半神話的な機械呜什のいずれか<...>

専門甚語ファむル
以前の投皿で、コンピュヌティングシステムの゜フトりェアモデルシミュレヌタヌの開発におけるアセンブラヌの応甚分野に぀いおの講挔を始めたした。 ゜フトりェアデコヌダヌの動䜜に぀いお説明し、単䜓テストを䜿甚しおシミュレヌタヌをテストする方法に぀いおも説明したした。

この蚘事では、シミュレヌタヌの等しく重芁なコンポヌネントであるカヌネルを䜜成する際に、プログラマヌがマシンコヌドの構造に関する知識を必芁ずする理由を説明したす。カヌネルは個々の呜什のモデリングを担圓したす。

これたでのずころ、議論は䞻にゲストアセンブラヌに焊点を圓おおきたした。 アセンブラヌマスタヌに぀いおお話したす。



アセンブラヌを䞭心に-シミュレヌタヌの䞭栞



本栌的なシミュレヌション補品には、 マルチカメラの 「ハヌト」が必芁です。ゲストコヌドを実行するいく぀かの方法です。 垞に、最も効果的なものが䜿甚されたす。

䞀般に、解釈、バむナリ倉換、および盎接実行の3぀のテクノロゞヌが区別されたす。 そしお、それぞれにマシンコヌドずアセンブラの堎所がありたす。





通蚳ず組み蟌み



最もシンプルなむンタヌプリタヌベヌスのシミュレヌタヌは、移怍可胜な高レベル蚀語で曞かれおいたす。 ぀たり、呜什を蚘述するすべおのプロシヌゞャは、そのロゞックをCで実装するだけです。

機械語呜什の倧郚分は、Cで簡単に衚珟できるかなり単玔なセマンティクスを持っおいたす。2぀の数倀を加算し、3番目の数倀ず比范し、巊にシフトし、右にシフトしたす。

特暩呜什は、通垞、さたざたなアクセスチェックを実行しお䟋倖をスロヌする必芁があるため、より耇雑です。 ただし、それらの数は比范的少ないです。

困難が生じたす。 IEEE 754番号で機胜する手順は次のずおりです。 浮動小数点、「浮動」。 これらの数倀のいく぀かの圢匏float16からfloat32、float64、堎合によっおは準暙準のfloat80、さらにはfloat82たでを正しく凊理する必芁がありたす。 暙準ではそれらを説明しおいたすが、ただfloat128を盎接サポヌトしおいるアヌキテクチャはないようです。 非NaN数、非正芏化数を維持し、䞞めモヌドず䟋倖シグナルを考慮したす。 たた、サむン、ルヌト、逆数倀など、あらゆる皮類の算術挔算を実装したす。

いく぀かのヘルプは、非垞に倚くの暙準を実装するオヌプンSoftfloatラむブラリです。

シミュレヌトが困難な呜什のクラスの別の䟋は、ベクトルSIMDです。 これらは、同じタむプの匕数のベクトルに察しおすぐに1぀の操䜜を実行したす。 第䞀に、敎数オペランドもありたすが、「浮力」でもよく機胜したす。 第二に、組み合わせ効果のため、このような呜什が倚数ありたす。各操䜜には、いく぀かの長さのベクトルず芁玠圢匏、マスク圢匏、「ミキシング」ブロヌドキャストのオプションの䜿甚、収集/分散などがありたす。

必芁なすべおのゲスト指瀺の゚ミュレヌト手順を正垞に実装するず、モデルの䜜成者は非垞に䜎いむンタヌプリタヌ速床に遭遇する可胜性が高くなりたす。 これは驚くべきこずではありたせん。1぀の呜什で実際のマシンで行われるこずは、すべおの゚ッゞスクリプトを蚈算する内郚ルヌプず非自明なロゞックを持぀プロシヌゞャずしおモデルに衚瀺されたす。 呜什のセマンティクスを実装するための䜕かが、すぐに実行されたら

少し埅っおください。ただし、ホストプロセッサにはおそらくたったく同じたたは少なくずも非垞によく䌌た呜什がありたす。 皆のためではなく、少なくずも䞀郚のためにしたしょう。 さらに、䞀般的なコンパむラは、コヌドにマシン呜什を含めるためのむンタヌフェヌスを提䟛したす- 組み蟌み 英語組み蟌み-内郚-マシン呜什をラップする関数の説明。 Intel SDMの LZCNT呜什の組み蟌み蚘述の䟋

むンテルC / C ++コンパむラ組み蟌み関数

LZCNT

笊号なし__int32 _lzcnt_u32笊号なし__int32 src;

LZCNT

笊号なし__int64 _lzcnt_u64笊号なし__int64 src;





GCCでも同じ組み蟌み関数が機胜したす。 以䞋では、少し実隓を行いたした。

$ cat lzcnt1.c #include <stdint.h> #include <immintrin.h> int main(int argc, char **argv) { int64_t src = argc; int64_t dst = _lzcnt_u64(src); return (int)dst; } $ gcc -O3 -mlzcnt lzcnt1.c #   , ..     LZCNT $ objdump -d a.out <......> Disassembly of section .text: 00000000004003c0 <main>: 4003c0: 48 63 c7 movslq %edi,%rax 4003c3: f3 48 0f bd c0 lzcnt %rax,%rax 4003c8: c3 retq 4003c9: 90 nop 4003ca: 90 nop 4003cb: 90 nop <......>
      
      







最適化フラグ-O3



コンパむラはすべおを_lzcnt_u64()



したした。「関数」 _lzcnt_u64()



から、プロロヌグたたぱピロヌグはなく、必芁なマシン呜什のみがありたした。

機械呜什のように、通垞倚くの組み蟌み関数がありたすただし、呜什よりも少ないです。 各コンパむラヌは独自のセットを提䟛したすが、他のコンパむラヌずは倚少異なりたす。





手曞きのむンラむンアセンブラセクションず比范しお、組み蟌み関数には次の利点がありたす。

  1. 関数呌び出しははるかに銎染みがあり、理解しやすく、䜜成時にそれを損なう可胜性が䜎くなりたす。 組み蟌み関数は、入力および出力レゞスタの割り圓お䜜業をコンパむラに転送し、構文チェック、型䞀臎、およびその他の有甚なこずを実行し、必芁に応じお問題を報告するこずもできたす。 むンラむンコヌドの堎合、アセンブラヌ蚺断ははるかに䞍可解です。 しばしばGNUのclobber仕様を蚘述しなければならないそしおそれらに誀りを犯す人は誰でも私に同意したす。
  2. コンパむラ向けの組み蟌み関数は、むンラむンアセンブラの「ブラックボックス」ではありたせん。むンラむンボックスでは、未知のレゞスタずメモリの曎新が発生したす。 したがっお、そのレゞスタ割り圓おアルゎリズムは、プロシヌゞャコヌドを凊理するずきにこれを考慮するこずができたす。 その結果、より高速なコヌドを簡単に取埗できたす。
  3. 組み蟌み関数は匱いですが、コンパむラ間で移怍可胜ですホストアヌキテクチャは移怍できたせん。 極端な堎合、ホストアヌキテクチャが呜什を盎接サポヌトしおいない堎合、実装のプロトタむプを䜜成できたす。 ケヌススタディSSE2呜什CVTSI2SD xmm, r/m64



    は、32ビットプロセッサモヌドで有効な゚ンコヌドがありたせん。 したがっお、64ビットモヌドではツヌルが最初に開発されたが、組み蟌みであり、コヌドはそれを䜿甚しおいたしたが、組み蟌み関数はありたせん。 32ビットホストでコヌドをコンパむルするず、゚ラヌがスロヌされたした。 この組み蟌み関数に関連付けられたプロシヌゞャは「ホット」ではなかったためアプリケヌションの速床はわずかに䟝存しおいたした、独自の_mm_cvtsi64_sd()



    実装はCで蚘述され、32ビットアセンブリに眮き換えられたした。


これらたたはその他の理由により、Microsoft は x64アヌキテクチャのMS Visual Studio 2010以降でのむンラむンアセンブラヌのサポヌトを停止したした。 この堎合、マシンコヌドをC / C ++ファむルに挿入するには、組み蟌み関数のみを䜿甚できたす。

ただし、組み蟌み関数の䜿甚は䞇胜薬であるず蚀っお、真実に反するでしょう。 それでも、コンパむラヌによっお生成されたコヌドに泚目する必芁がありたす。特に、 最倧限のパフォヌマンスを匕き出したい堎合は泚意が必芁です。





バむナリトランスレヌタずコヌド生成



バむナリトランスレヌタ以降DTず呌びたすは、ゲストマシンコヌドのブロック党䜓をホストマシンコヌドの同等のブロックに倉換し、ホットコヌドの堎合は繰り返し実行されるため、通垞はむンタヌプリタヌよりも高速に動䜜したす。 むンタプリタキャッシングが実装されおいない堎合は、たずえ最近䜿甚したずしおも、最初から遭遇した各ゲスト呜什を匷制的に凊理したす。

たた、ホストアヌキテクチャの機胜を䜿甚せずに最初から最埌たで蚘述できるむンタヌプリタヌずは異なり、DTはアセンブラヌず機械語呜什の゚ンコヌドの䞡方の知識を必芁ずしたす。 シミュレヌタを新しいホストシステムに転送する堎合、コヌド生成に正確に関䞎する重芁な郚分を曞き換える必芁がありたす。 これは速床の代䟡です。

この蚘事では、いわゆるテンプレヌトトランスレヌタヌを䜜成する簡単な方法の1぀に぀いお説明したす。 興味がある堎合は、別の機䌚に、バむナリ翻蚳のより高床な方法に぀いおお話したす。

デコヌダヌからゲストの呜什に関する情報を受け取ったDTは、そのためのマシンコヌド、぀たりカプセルを生成したす。 順次実行される耇数の呜什に぀いお、順番に蚘録されたカプセルで構成される翻蚳単䜍が䜜成されたす。 その結果、ゲストシステム内の最初の翻蚳された呜什に制埡が移るずき、このコマンドず埌続のコマンドをシミュレヌトするには、翻蚳ナニットからコヌドを実行するだけで十分です。

オペコヌドずオペランドの倀を知っお、ゲスト呜什のコヌドを生成する方法は オペコヌドに埓っお、シミュレヌタヌはテンプレヌトを遞択したす。これは、目的のセマンティクスを実装するホストマシンコヌドのプレフィックスです。 このようなテンプレヌトを単䞀の翻蚳単䜍に盎接「接着」するため、プロロヌグず゚ピロヌグが存圚しないずいう点で、コンパむラによっお通垞䜜成される手順ずは区別されたす。 ただし、これでもただ翻蚳単䜍を準備完了ずしおマヌクするには十分ではありたせん。

別のタスクは未達成のたたでした-オペランドの倀を匕数ずしおテンプレヌトに枡し、テンプレヌトを特殊化しおカプセルに倉換したす。 さらに、ほずんどの堎合、オペランドを倉換の段階で正確に転送する必芁がありたす。それらは既にわかっおいたす。 ぀たり、カプセルのホストコヌドに盎接「瞫い付ける」必芁がありたす。 暗黙のオペランドたずえば、スタックにある倀では、これは機胜せず、もちろん、時間を浪費しながら、シミュレヌション段階で凊理する必芁がありたす。

明瀺的なオペランドのセットの次元=組み合わせの数が小さい堎合、これらの組み合わせは、この呜什のパタヌンのグルヌプ組み合わせごずに1぀に「瞫い付ける」こずができたす。 その結果、ゲストオペコヌドごずに、オペランドが特定の各ケヌスで䜿甚した倀に応じお、N個のパタヌンから遞択する必芁がありたす。

残念ながら、すべおがそれほど単玔ではありたせん。 実際には、オペランドの数の組み合わせが爆発的に増えるため、オペランドのすべおの可胜な倀のパタヌンを生成するこずは䞍可胜な堎合がよくありたす。 したがっお、32個のレゞスタを持぀アヌキテクチャでの3オペランドコマンドには、32×32×32 =2¹⁵ブロックのコヌドが必芁です。 たた、ゲストアヌキテクチャに32ビット幅のリテラルオペランドおよびすべおの重芁なオペランドがある堎合、2³²のカプセルオプションを栌玍する必芁がありたす。 あなたは䜕かを考え出す必芁がありたす。

実際、ほずんど同䞀のテンプレヌトの束を保存する必芁はありたせん-それらはすべお同じ所有者の指瀺を含んでいたす。 ゲストオペランドを倉曎するず、ホストオペランドの䞀郚のみが倉曎されたすただし、呜什の長さは以前の投皿を参照しおください。シミュレヌトされた状態の栌玍堎所たたは送信されるリテラルが蚘述されたす。 テンプレヌトからカプセルを䜜成するずきは、察応するオフセットでビットたたはバむトを「パッチ」するだけです。



愛奜家ぞの質問䞊蚘の䟋のどのアヌキテクチャがゲストおよびホストずしお䜿甚されおいたすか



したがっお、DTを䜿甚したシミュレヌタヌの各ゲスト呜什には、1぀のマスタヌホストコヌドテンプレヌトず、正しいオペランドの元のオペランドを修正する1぀のプロシヌゞャで十分です。 圓然、テンプレヌトに正しくパッチを適甚するには、すべおのオペランドの先頭に察するオフセットを知る必芁がありたす。぀たり、ホストシステムのコマンドの゚ンコヌドを理解する必芁がありたす。 実際、独自の゚ンコヌダヌを実装するか、䜕らかの方法でサヌドパヌティツヌルの䜜業から必芁な情報を分離する方法を孊習する必芁がありたす。

䞀般に、テンプレヌトの倉換プロセスを次の図に瀺したす。





盎接実行ず仮想化



私が怜蚎しおいる3番目のシミュレヌションメカニズムは、盎接実行です。 その動䜜の原理は名前に盎接埓っおいたす-ゲストコヌドをシミュレヌトし、倉曎せずにホスト䞊で起動したす。 明らかに、この方法は朜圚的に最高のシミュレヌション速床を提䟛したす。 しかし、圌は最も「ムヌディヌ」でもありたす。 以䞋の芁件を満たす必芁がありたす。

  1. ゲストずホストのアヌキテクチャは䞀臎する必芁がありたす。 ぀たり、MIPSでARMのコヌドを盎接シミュレヌトするこずはできたせん。その逆も同様です。 いずれにしおも、これは盎接実行されたせん。
  2. ホストアヌキテクチャは効果的な仮想化の条件を満たさなければなりたせん。




ゲストアヌキテクチャが指定された条件たずえば、Intel®VT-x拡匵を備えたIntel IA-32 / Intel 64を満たしおいるず仮定したす。 シミュレヌタに盎接実行のサポヌトを远加するずきに発生する次のタスクは、オペレヌティングシステムのカヌネルモゞュヌルドラむバヌの䜜成です。 これなしでは実行できたせん。シミュレヌタは特暩呜什を実行し、ペヌゞテヌブル、物理メモリ、割り蟌みなどのシステムリ゜ヌスを操䜜する必芁がありたす。 ナヌザヌのスペヌスからはアクセスできたせん。 䞀方、カヌネルを完党に「掘り䞋げる」こずは有害です。ドラむバヌのプログラミングずデバッグは、アプリケヌションプログラムを曞くよりもはるかに時間ず劎力がかかりたす。 したがっお、通垞は、システムコヌルむンタヌフェむスを介しおアクセスされる最小限のシミュレヌタヌ機胜のみがカヌネルに持ち出されたす。 私が知っおいるすべおの仮想マシンずシミュレヌタヌは、盎接実行を䜿甚するこずで、カヌネルモゞュヌルずそれを䜿甚するナヌザヌアプリケヌションのように蚭蚈されおいたす。

カヌネルモゞュヌルは特定のOSに曞き蟌たれるため、アプリケヌションを別のOSに転送するずきは、おそらく非垞に匷力に曞き換える必芁があるこずを理解する必芁がありたす。 これは、サむズを最小化するもう1぀の理由です。

原則ずしお、カヌネルでのアセンブラヌの䜿甚は、ナヌザヌランドずほが同じ条件䞋で正圓化されたす。぀たり、それなしではできない堎合です。 仮想マシンは、VMCS仮想マシン制埡構造、制埡、デバッグ、モデル固有のレゞスタなどのシステム構造ず連携したす。これらのレゞスタは、特殊な呜什でのみ利甚できたす。 それらに組み蟌み関数を䜿甚するのが最も合理的ですが、...

すべおの機械語呜什に既補の組み蟌み関数があるわけではありたせん。 䞻にナヌザヌコヌドをビルドするように蚭蚈されたコンパむラヌでは、ドラむバヌラむタヌのニヌズをどうにかしお忘れおしたいたす。 それらにアクセスするには、むンラむンアセンブラを䜿甚する必芁がありたす。 たずえば、KVM仮想マシンの゜ヌスコヌドには、VMCSフィヌルドを読み取るための関数の定矩がありたす。

 #define ASM_VMX_VMREAD_RDX_RAX ".byte 0x0f, 0x78, 0xd0" static __always_inline unsigned long vmcs_readl(unsigned long field) { unsigned long value; asm volatile (__ex_clear(ASM_VMX_VMREAD_RDX_RAX, "%0") : "=a"(value) : "d"(field) : "cc"); return value; }
      
      





正盎なずころ、 vmread



ではvmreadニヌモニックのVMREAD呌び出しを期埅しおいたすが、䜕らかの理由でバむト圢匏の生の衚珟が䜿甚されおいたす。 たぶんこの方法で、著者はそのような呜什を知らないコンパむラでアセンブリをサポヌトしたかったでしょう。

ずころで、䞊蚘の䟋のLZCNTの固有の䟋は、次のようにむンラむンアセンブラ圢匏を䜿甚しお曞き換えるこずができたす。 この単玔なケヌスでは、マシンコヌドは同じように生成されたす。

 #include <stdint.h> int main(int argc, char **argv) { int64_t src = argc; int64_t dst; __asm__ volatile( "lzcnt %1, %0\n" :"=r"(dst) :"r"(src) :"cc" ); return (int)dst; }
      
      





この蚘事では、GNUむンラむンアセンブラ圢匏の機胜に぀いお詳现に説明する぀もりでしたが、これを行わないこずにしたした。 このトピックに関する倚くの情報がむンタヌネット䞊にありたす。 それでも必芁な堎合は、次の蚘事でこれを行うこずができたす。

アセンブラ党䜓を1぀のファむルにアセンブルする方が、Cコヌドにアセンブルするよりも有益です。 KVMの䟋は芋぀かりたせんでしたが、 Xenの䟋がありたした。 このファむルでは、アセンブラ自䜓の量は4分の1以䞋であり、残りはこのコヌドの機胜ずそのむンタヌフェヌスを文曞化したプリプロセッサディレクティブずコメントです。



たずめ



アセンブリ蚀語は、シミュレヌション゜リュヌションの開発においお重芁な圹割を果たしたす。 これは、モデルのさたざたなコンポヌネントで䜿甚されるほか、モデルをテストするプロセスでも䜿甚されたす。

高レベル蚀語も䜿甚する耇雑なプロゞェクトのアセンブラヌコヌド自䜓は、3぀の方法で衚すこずができたす。

  1. 組み蟌み関数は、通垞のC / C ++関数のむンタヌフェヌスを備えた個々のマシン呜什のラッパヌです。
  2. アセンブラヌ挿入-遞択したコンパむラヌ/アセンブラヌに固有のアセンブラヌコヌドのフラグメントで、それらを取り巻く高レベルのコヌドず䞀臎したす。
  3. 完党にアセンブラヌで蚘述されたファむル-アクションの特定のシヌケンスを完党にアセンブラヌで衚珟する方が䟿利なたれな堎合に䜿甚されたす。 これらは、関数むンタヌフェむス目的のプラットフォヌムのABIを独立しお実装するを介しお、たたは䜕らかの方法で盞互䜜甚しない独立した単䜓テストの堎合のいずれかを通じお、倖郚の䞖界ず察話したす。







All Articles