HN 日本語サマリー

← 一覧へ戻る
プログラミング

x86エミュレーションの弊害

The Scourge of x86 Emulation (fex-emu.com)

21 pointsby dagmx0 コメント

要約

この記事は、ARMのような弱順序メモリモデル上でx86のTotal Store Ordering (TSO) メモリモデルをエミュレートする際の複雑な問題について解説しています。x86-TSOの厳格なメモリ順序付けをARMの緩和されたモデルで再現するには、特別なロード・ストア命令が必要となり、これがパフォーマンスの低下を引き起こす原因となります。ARMv8.3以降で導入されたLRCPC (Load-Reserved/Conditional-Store-Conditional) 命令は、この問題に対する有望な解決策を提供し、エミュレーションのパフォーマンスを大幅に向上させる可能性を示唆しています。

全文翻訳

x86エミュレーションの弊害 当サイト初の特集記事へようこそ。今回は、私たちがエミュレートするすべてのアプリケーションに影響を与える、x86エミュレーションにおける継続的な問題について取り上げます。これは、広範な影響を持つ単一の包括的な用語、すなわちx86 Total Store Orderingメモリモデル(x86-TSO)のエミュレーションに帰着します。ARMが定義する弱順序メモリモデル上でこのメモリモデルをエミュレートすることに伴う問題は多岐にわたり、複数の課題を網羅しています。この記事では、遭遇する可能性のあるすべての問題と、それらを解決する方法(あるいは、場合によっては解決できない方法)について説明します。スナックと温かい飲み物を用意して、ゆっくりお楽しみください。これは長くなるでしょう。 x86-TSOとは何か? ARMv8.0-aのささやかな始まり メモリへのアクセスは簡単な部分だと思っていましたか?いやいや、アトミック命令とは何ですか?スプリットロックが必須だとはどういうことですか?キャッシュされないメモリが機能する必要があるとは? より明るい未来に向けて x86-TSOとは何か? x86メモリモデルの問題を回避する方法を詳しく説明する前に、それが正確に何であるかをまず議論する必要があります。メモリモデルとは、システム内のメモリアクセスが互いにどのように振る舞うかについてのルールのセットです。これらのルールは、シングルスレッド環境またはマルチスレッド環境におけるロードとストアの相互作用を決定します。ハードウェアのさまざまな形態で実装されている一般的なメモリモデルがいくつかありますが、今日私たちが気にするのは、ARMの緩和された(または弱い)一貫性モデルと、x86のTotal-Store-Ordering一貫性モデルのバリアントの2つです。これら2つのモデルは基本的にスペクトルの両極端です。ARMは最も緩和されており、大幅なハードウェア最適化を可能にしますが、x86は最も厳格であり、多くの最適化の余地を残さない非常に強力なコヒーレンシモデルを強制します。 メモリモデルについて議論する際に注意すべき点は、一貫性とアトミック性の違いです。これらは関連していますが、同じではなく、すべてのケースで保証されるわけではありません。メモリモデルの違いがどのように機能するかを説明する最良の方法は、x86がこれをどのように処理するかから始めることです。TSOは非常に厳格に動作するため、プログラマーはメモリストアが発生した場合、それがシステム内の他のすべてのプロセッサに対して一貫して可視になると想定できます。さらに、メモリロードが発生した場合、それ以前のすべてのストアは「論理的に」完了しているか、少なくとも可視になっていることを意味します。これはプログラマーの期待と一致します。メモリに書き込むと、書き込み時点で見えるようになり、プログラミングを考える上で直感的です。ストアは実質的にロードの可視性を順序付けるため、モデルの名前が付けられています。これがどのように機能するかにはニュアンスがありますが、理解するために厳密に必要ではありません。 ARMの弱いメモリモデルは、その動作について少し直感的ではありません。デフォルトでは、ARMが使用する通常のメモリロードとストアは、システム内のプロセッサ間で厳密に一貫しているわけではなく、CPUがほとんどの場合、より効率的に動作できるようになります。ストア命令が実行されると、そのメモリ(キャッシュライン)はシステム内の他のプロセッサにすぐに可視になるわけではありません。他のコアのキャッシュラインを無効にしたり、他のプロセッサのキャッシュをスヌープさせたりするのはハードウェアにとってコストが高いため、貴重な電力と効率を節約します。同様に、プロセッサが別のプロセッサが書き込んだデータからメモリをロードしている場合、このロードがこの更新されたメモリを見ることは保証されません。これはマルチスレッドアプリケーションで重大な問題を引き起こすように聞こえませんか?ARMの古いバージョン(ARMv7以前)は、メモリバリア命令を使用して順序付けを保証していましたが、これはパフォーマンスに大きな影響を与えました。この一貫性の制限を回避するために、ARMはロード・アキュアアキュア(load-acquire)およびストア・リリース(store-release)メモリ命令も導入しました。C++の専門用語では、これはそれぞれstd::atomicのmemory_order_acquireおよびmemory_order_releaseの定義にマッピングされます。ARMの用語では、これらの命令も技術的にはアトミック操作とは見なされませんが、プログラマーはこれらを混同します。FEXは、アトミックロードとアトミックストアという用語を同じ意味で使用しています!通常、この区別は問題になりませんが、これらのトピックについて議論する際には、 pedantic になる方が良いかもしれません。これらの命令の主なユースケースは、これらのクラスの命令間のメモリ順序付けを強制することです。ARMはこれを「Release Consistency sequentially consistent (RCsc)」モデルと呼んでいます。このモデルがどのように動作するかについてあまり深く掘り下げることなく、基本的な要点は、ロード・アキュア命令は再順序付けなしで順次観測されなければならず、ストア・リリース命令も同様に「barrier-ordered-before」セマンティクスを満たしながら観測されなければならないということです。 古いARMアーキテクチャバージョンで必要とされたコストのかかるメモリバリア命令を削除します。 ARMv8.0-aのささやかな始まり これが、x86-TSOメモリモデルをエミュレートする際のARMv8.0-aの出発点です。すべてのx86メモリロードをARMのロード・アキュア命令に、x86メモリストアをストア・リリース命令に変換します。これにより、FEXは実質的にx86と同じメモリセマンティクスを得ますが、実際には必要以上に厳格になっています。なぜなら、正確に一致する中間的な選択肢がなかったからです。想像できるように、これらの命令でTSOをエミュレートするのは非常にコストがかかり、それを証明するマイクロベンチマークがあります。ARM CPUは、これらの比較的まれなアキュア/リリース命令が突然実行される命令の大部分になるように設計されていなかったためです。 まず、簡単なものから始め、ハードウェアにかなり優しいマイクロベンチマークを使用しましょう。トリッキーなエッジケースはなく、一般的なケースでメモリにアクセスするだけです。これにより、最良の場合の状況がどうなるかのベースライン数値が得られます。 このグラフを分解すると、いくつかの興味深い物語が語られています。各マシンのロードとストアの列は、ハードウェアが達成しようとしているベースラインパフォーマンス数値を表しています。これらはシステムのメモリ帯域幅を最大化しようとしているわけではありませんが、各操作タイプで同じ量の作業を行っています。 アキュアロードの結果に目を向けると、テストされた5つのCPUのうち3つで、アキュアロードの使用によってパフォーマンスがかなり低下していることがわかります!さらに、AmpereOne CPUは他の結果と比較してストア・リリース命令のパフォーマンスが著しく低く、M1のアキュア/LRCPCロード命令もベースラインよりもかなり低いことがわかります。特にAmpereOneの結果は、このレガシーパスがどれほど悪いかを示しています。これらの命令は、このように使用されるようには設計されていませんでした。 x86エミュレーションのためにすべてのアキュア・リリースセマンティクスを使用すると、ARM CPUに非常に厳しい制限が課せられます。なぜなら、ロード命令は互いに順序付けできなくなるからです。したがって、毎秒数百万もの命令が実行される場合、パフォーマンスが良好であるとは期待できません。しかし、ARMv8.0-aで利用できる命令はこれしかなかったため、これを使用するしかありませんでした。 Cortex-X4およびCortex-X925はこれらの命令で驚異的なパフォーマンスを発揮しますが、Oryon-3がそれらの重要性をどのように軽視しているかがわかります。 これからどうなるか? LRCPCロード命令を詳しく見てみましょう。これはARMv8.3以降で必須です。この拡張機能は、ARM ISAに多くの新しいロード命令を追加し、以前のARMのRCscモデルの上に新しいメモリモデルを追加します。この新しい「Release Consistency processor consistent (RCpc)」メモリモデルこそ、私たちが求めていたものです!この拡張機能は、x86エミュレーションが必要とする要件を中心に設計されており、それを実装するハードウェアで広く利用されることが期待されています。 グラフからわかるように、ほとんどすべてのプラットフォームでLRCPCロードのパフォーマンスは通常のロードと同等です。新しいARMバージョンで義務付けられているこの新しい拡張機能により、メモリパフォーマンスの問題は基本的に解決されます。少なくとも、によると