FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

"Constructing a Weak Memory Model" を読む (3. モデルの構築)

Weak Memory Modelについてもう少し知識をつけたかったので、論文を読んでみることにした。

arxiv.org

基本的にDeepLに翻訳してもらったものを、自分で読み直しながら直しているだけなので、自分でまとめているわけではない。 冗長なのは無編集でブログに貼っている、ということで。


III. GAMの直感的な構築

まず、高度に最適化されたアウト・オブ・オーダー・ユニプロセッサOOOUを研究し、そのようなアグレッシブな実装であっても、シングル・スレッド・セマンティクスを維持するためにいくつかの順序制約を守ることを示す。複数のOOOUがアトミック・メモリ・システムを介して接続され、マルチプロセッサOOOMPを形成する場合、これらの制約を拡張して、OOOMPの動作を特徴付け、ユニプロセッサ最適化を維持するという目標を満たすベース・メモリ・モデルを形成することができる。

しかし、すべてのマルチスレッド・プログラムに対してSCをリストアする方法がないため、基本モデルはプログラム不可能である。

そのため、OOOMPの排他順序を制御するフェンス命令を導入する。すなわち、ウィーク・メモリ・モデルを持つマシンをプログラミングする場合でも、プログラマが一般的に想定する順序を壊さないようにする。プログラマーの直感に合わせるために、我々は構築されたモデルにさらなる制約を導入する。これらの制約が性能に与える影響についてはセクションVで検討する。

A. アウトオブオーダー・ユニプロセッサ(OOOU)

図6に、ライト・バック・キャッシュ階層に接続されたOOOUの構造を示す。メモリアクセスがキャッシュミスになった場合、プロセッサはその行をL1にフェッチしてからアクセスする。メモリ・システムは、複数の要求を並列に処理することができるが、同じアドレスに対する要求は、メモリ・システムに発行された順に処理される。説明を簡単にするため、メモリモデルに関係のない詳細は省略する。OOOUは次の命令を投機的にフェッチし、フェッチされた命令はすべて順番にROBに挿入される。ロードとストアも、それぞれロードバッファ(LB)とストアバッファ(SB)に同じ順序で挿入される。

OOOUは命令を順序を無視して投機的に実行するが、投機に関して以下の2つの制限を仮定する:

  1. メモリ・システムに送られたストア要求は撤回できず、その効果を取り消すこともできない。
  2. 命令の次の PC 以外の宛先レジスタの値は決して予測されない(すなわち、OOOU は値予測を行わない[72]-[78])。

最初の制限は受け入れやすいが、2 番目の制限はセクション III-D2 で正当化される。投機に関する制限は、命令を発行して実行を開始できる必要条件を意味する。例えば、すべてのソース・オペランドがレディになるまで(すなわち、古い命令によって計算されるまで)、命令は発行できない。命令(特にストア)を発行する際の他の制約については、後述する。発行された後、reg-to-reg命令または分岐命令は、ローカル計算だけで実行される。ストアの実行は、メモリシステムにストア要求を送る。転送が不可能な場合、ロードはメモリシステムに要求を送る。

アウト・オブ・オーダ実行にもかかわらず、OOOUは依然としてROBからの命令を順番にコミットする。ストアは、コミット時にメモリシステムへのストア要求を完了する必要はないが、ロード、reg-to-reg、ブランチ命令は、コミット時にその値を取得している必要がある。以下では、ある命令I1が別の命令I2より古いという場合、デフォルトでは、コミット順序においてI1がI2より前にある(あるいは、I1がI2より前にROBに挿入されている)ことを意味する。

ユニプロセッサにおける命令の並べ替え: 命令の並び替えとは、2つの命令の実行順序がコミット順序と異なることを意味する。実行順序とは、命令の実行が終了する時刻の順序のことである。 reg-to-reg命令や分岐命令は、それぞれ目的レジスタの値を計算したり、次のPCを解決したりした時点で実行を終了する。ロード命令は、SBから転送を受けるか、L1からデータを読み出すときに実行を終了する。ストアは、ストアデータをL1キャッシュのデータ配列に書き込んだ時点で実行を終了する。コミットされる前に(例えばミススペックのために)つぶされた命令は、実行順序のメンバーではない。

B. OOOUにおける制約

OOOUの実行順序に関するすべての制約を図7に列挙し、1つずつ導出する。

これらの制約は、2つのカテゴリーに分類できる。最初の制約セット(SAMemStSAStLd)は、同じアドレスに対するメモリ命令間の制約であり、シングルスレッドの正しさを維持するために不可欠である。第2の制約セット(RegRAWBrStAddrSt)は、命令を発行して実行を開始する前に満たす必要がある必要条件を反映している。投機的実行は、このような条件の多くを取り除くことができるが、投機に関するいくつかの制約を仮定しているため、いくつかはまだ残っている。

  • SAMemSt(same-address-memory-access-to-store)制約: ストアは、同じアドレスに対する古いメモリ命令の後に命令されなければならない。
  • SAStLd(同一アドレス-ストア-ロード)制約: ロードは、同じアドレスに対して直前のストアのアドレスまたはデータを生成するすべての命令の後に命令されなければならない。
  • RegRAW(register-read-after-write)制約: 命令は、PC以外のソースオペランドの1つを生成する古い命令の後に命令されなければならない。
  • BrSt(分岐-ストア)制約: ストアは、古い分岐の後に命令されなければならない。
  • AddrSt(アドレスからストア)制約: ストアは、ストアよりも古いメモリ命令のアドレスを生成する命令の後に命令されなければならない。

同じアドレスのメモリ命令に対する制約: I1とI2が同じアドレスaに対する2つのメモリ命令で、I1の方がI2より古いとする。I1とI2の両方がロードであれば、それらの実行を順序付ける必要はない。I2がストアの場合、I1がロードであろうとストアであろうと、I1の実行が終了する前にL1を書き込むことはできない。したがって、図7のSAMemSt制約がある。

次に、I1がストア、I2がロードの場合を考える。I2がL1をリードして実行される場合、I1がL1を書き込む前に実行することはできない。従って、これら2つの命令が並び替えられる唯一の方法は、図8に示すように、I2がストアSから転送を受けるときである。SはI2より古い最も若いストアでなければならない。フォワーディングのためにI1とI2の間に直接的な順序制約が存在することはできないが、I2が潰されることなく最終的にコミットされた場合、I2はSのアドレスとデータが古い命令によって計算される前に実行を開始することはできない。これにより、図7のSAStLd制約が得られる。

実行開始命令の制約 すべてのソースオペランドが準備できていなければ、命令を実行に移すことはできないので、図7にRegRAW制約がある。この制約ではPCを除外していることに注意されたい。

これは、OOOUが分岐予測を行うためであり、フェッチされた命令はすでにPCを知っており、実行に使用することができる。

制約RegRAWは、reg-to-reg命令、分岐命令、ロード命令の発行要件をすでにカバーしている。特に、ロードの発行に関しては、投機のためこれ以上の制約はない。例えば、図9のプログラムを考える。OOOUは、I2のアドレスがI3と同じであることが判明しても、I2のストア・アドレスが計算される前(すなわち、I1が実行を終了する前)に、I3のロードを発行することができる。I1がr1に値bを本当に書き込んだ場合、OOOUはI3をつぶして再実行する。I1とI3の間の実行順序は、制約SAStLdによって捕捉された。

次に、投機的ストアの発行禁止という制約によって引き起こされる制約を考える。単純なケースは、古い分岐が実行されていないときにはストアを発行できないというもので、図7の制約BrStである。これは、分岐がフェッチ時に誤って予測され、将来ROBスクワッシュを引き起こす可能性があるためである。もう1つのケースは、古いメモリ命令のアドレスが準備できていないときにストアを発行できないこと、すなわち図7の制約AddrStである。これは、ストアを発行し、後で古いメモリ命令のアドレスがストアのアドレスと同じであることが判明した場合、シングルスレッドの正しさ(すなわち制約SAMemSt)に違反する可能性があるためである。