Chrome for WindowsでGoogleに勤務している開発者であるBruce Dawsonによる最新記事の翻訳に注目してください。Meltdownと
Spectreの脆弱性の最近の発見は、Xbox 360プロセッサで同様の脆弱性を発見したときのことを思い出しましたが、これはプロセッサに最近追加された命令によるもので、まさにその存在が危険でした。
2005年、私はXbox 360プロセッサーに携わり、このチップだけで生きて息をしました。 壁にはまだ直径30 cmの半導体ウエハーがあり、このCPUのアーキテクチャを示す1.5メートルのポスターがあります。 プロセッサコンピューティングパイプラインがどのように機能するかを理解するのに多くの時間を費やしたため、不思議なクラッシュの原因を見つけるように頼まれたとき、プロセッサ設計のエラーがその外観につながる可能性があることを直感的に推測できました。
ただし、問題自体に進む前に、まず少し理論を説明します。

Xbox 360は、IBM製のトリプルコアPowerPCチップです。 3つのコアはそれぞれ個別の象限にあり、4番目の象限は1 MB L2キャッシュ用に予約されています-これはすべて隣の画像で確認できます。 各コアには、32 KBの命令キャッシュと32 KBのデータキャッシュがあります。
事実:コア0は物理的にL2キャッシュに最も近い場所にあったため、L2キャッシュにアクセスする際の遅延時間が大幅に短くなりました。すべてのXbox 360プロセッサの
レイテンシは
高く 、特にメモリレイテンシは悪かった。 さらに、1 MBのL2キャッシュ(およびプロセッサに収まるのはそれだけです)は、トライコアCPUには十分ではありませんでした。 したがって、キャッシュミスを最小限に抑えるために、L2キャッシュのスペースを節約することが重要でした。
ご存知のように、
空間的局所性と
時間的局所 性により、プロセッサキャッシュはパフォーマンスを向上させ
ます 。 空間的ローカライズとは、次のことを意味します。1バイトのデータを使用した場合、すぐに他の隣接バイトのデータを使用する可能性があります。 一時的-何らかの種類のメモリを使用した場合、近い将来再び使用する可能性があります。
さらに、一時的な局所性が実際に発生しない場合があります。 大きな
フレームごとに1回のデータ配列を処理している場合、それが再び必要になるまでにL2キャッシュを離れることが簡単に証明できます。 空間的局所性の恩恵を受けることができるように、データをL1キャッシュに保持する必要がありますが、そのデータがL2キャッシュに残り続けると、他のデータに取って代わり、他の2つのコアが遅くなる可能性があります。
これは通常避けられません。 PowerPCプロセッサのメモリコヒーレンスメカニズムでは、L1キャッシュからのすべてのデータもL2キャッシュにある必要がありました。 メモリの一貫性のために使用された
MESIプロトコルでは、1つのコアがキャッシュラインに書き込む場合、同じキャッシュラインのコピーを持つ他のコアはすべてドロップする必要があり、L2キャッシュはL1の追跡を担当する必要がありました-どのアドレスのキャッシュに関係するキャッシュ。
ただし、プロセッサはビデオゲームコンソール用であり、主な優先事項はパフォーマンスであったため、CPUに新しい命令xdcbtが追加されました。 通常のPowerPC命令
dcbtは、
プリフェッチの典型的な命令でした。
xdcbt命令は
prefetchを実行するための拡張命令で、L2キャッシュをバイパスして、メモリからデータを直接L1データキャッシュに
取得できました。 これは、メモリーの一貫性が保証されなくなったことを意味します-しかし、ゲーム開発者
は知っています 。
おっと...
Xbox 360でメモリをコピーするために頻繁に使用される関数を作成し、オプションで
xdcbtを使用し
ました 。
プリフェッチはパフォーマンスの鍵であり、通常は
dcbtを使用してい
ましたが、
PREFETCH_EXフラグを渡すと
xdcbtでフェッチし
ます 。 悲しいかな、実践が示しているように、これは間違った考えの決定であることが判明しました。
この機能を使用したゲーム開発者は、奇妙なクラッシュについて定期的に話していました。ヒープダメージが発生しましたが、メモリダンプのヒープ構造は正常に見えました。 ダンプのクラッシュが十分に見られたので、私は最終的にどこでミスを犯したのかを認識しました。
xdcbtを使用して選択されたメモリは「毒性」でした。 L1キャッシュからフラッシュされる前に別のカーネルによって書き込まれた場合、他の2つのコアは異なるメモリビューを持ち、それらのビューが一致するという保証はありませんでした。 Xbox 360のキャッシュラインは128バイトで、コピー機能はソースメモリの最後まで
到達しました。その結果、
xdcbtがキャッシュラインに適用され、その最後の部分は隣接するデータ構造の一部でした。 通常、それはヒープメタデータでした-少なくともクラッシュが観察されたのはそこでした。 一貫性のないカーネルは(ロックを慎重に使用しているにもかかわらず)古くなったデータを見つけてクラッシュしましたが、クラッシュダンプは
RAMの実際の内容を返したため、実際に何が起こっているのかわかりませんでした。
合計で、xdcbtを使用する唯一の安全な方法は、慎重にプリフェッチすることであり、これにより、バッファーの終了後1バイトでも入らないようになりました。 コピーメモリ機能を修正して、これまで「実行」されないようにしましたが、バグ修正を待たずにゲーム開発者が
PREFETCH_EXフラグの使用をやめただけで、問題は解消されました。
本当のバグ
それだけですよね? ゲーム開発者は火で遊んで、太陽に近づきすぎて飛んでしまい、ゲーム機のリリースはクリスマスをほとんど逃しました。 しかし、私たちはこの問題を時間内に見つけて解決し、コンソールとゲームをリリースする準備ができました-気楽に家に帰ります
そして、このゲームは再びクラッシュし始めました。
症状は同じでした-ゲームが
xdcbt命令を使用しなくなったことを除いて。 コードを段階的にデバッグすることができ、実際にそうであることがわかりました。 本当に深刻な問題に直面しているようです。
デバッグの最も古い方法に頼らなければなりませんでした-私は心をクリアし、コンピューティングパイプラインが私の潜在意識を満たせるようにしました-そして突然問題が何であるかを認識しました。 私はすぐにIBMに電子メールを書きましたが、内部プロセッサー構造の微妙な点(これまで考えもしなかった)に対する不安が確認されました。 悪役は
メルトダウンと
スペクターの場合と同じだった。
Xbox 360プロセッサは
、順序どおりの実行命令を
実行します。 実際、このプロセッサは非常にシンプルであり、高いパフォーマンスを実現するためにその高周波(予想されるほど高くはありませんが)に依存しています。 ただし、遷移の予測子が含まれています-非常に長いコンピューティングパイプラインのために必要です。 CPUパイプラインのデバイスを示す図は、すべてのパイプラインを示しています(詳細を知りたい場合は、
このリンクをお見逃しなく )。
この図では、遷移予測と、パイプラインが非常に長い(図の幅が広い)という事実の両方を見ることができます-
命令の順序に関係なく、
予測ミスした命令が残りに追いつくことができるように十分な長さです。
したがって、分岐予測子は予測を行い、予測された命令が選択、デコード、および実行されますが、予測が正しいかどうかがわかるまで削除されません。 おなじみの音? 私が自分のために発見したことは、これまで考えたこともなかったが、投機的にプリフェッチしたときに実際に何が起こったのかということだった。 遅延が大きいため、プリフェッチトランザクションをできるだけ早くバスに転送することが重要であり、フェッチが開始されると、それをキャンセルする方法はありませんでした。 したがって、投機的に実行された
xdcbtは実際の
xdcbtと同一
でした ! (投機的に実行されたブートコマンドは単なるプリフェッチでした)
それが問題でした。 ジャンプ予測子は、
xdcbtコマンドの投機的実行に
つながることがあり、実際の実行と同じくらい悪かった。 私の同僚の1人は、この理論をテストする興味深い方法を提案しました-ゲーム内のすべての
xdcbt呼び出しをブレークポイントに置き換えることです。 これにより、次の結果が得られました。
- ブレークポイントはもう機能しませんでした。これは、ゲームがxdcbtの指示に従っていないという事実によって証明されました。
- クラッシュはなくなりました。
私にとってこれは期待された結果でしたが、それでも非常に印象的でした。 数年後、
Meltdownについて読んだとき、従わなかった指示がクラッシュの原因になったのを見るのはまだクールでした。
遷移予測に関する私の洞察により、この命令はゲームのコードセグメントに含めるには危険すぎるため、命令を「投機的に」実行できるタイミングを制御するのが複雑すぎることが明らかになりました。 理論上、
分岐予測子は任意のアドレスを予測できるため、
xdcbt命令を配置する安全な場所はありません
でした 。 リスクは軽減される可能性がありますが、完全に除去されるわけではなく、努力する価値はありませんでした。
Xbox 360アーキテクチャの説明では引き続きこれらの手順を参照していますが、それを使用するゲームが少なくとも1つリリースされているとは思えません。
「あなたが遭遇した最も難しいバグを説明してください」という古典的な質問に答えてインタビュー中に、私はこのケースについて話しました。 インタビュアーの回答は「はい、
DEC Alphaプロセッサで似たようなものに出会いました」でした。
確かに、新しいものはすべて古いものです。