FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages/

プロセッサのメモリコンシステンシモデルについて

プロセッサ構成はますますマルチコア化しており、同期処理や各プロセッサでの通信、データ共有をどのように行うかという問題は重要になっている。

ハードウェア・ソフトウェアには「メモリモデル」というものが定義されており、共有する変数をどのようにして取り扱うか、レーシングの状態をどのように取り扱うかというものが定義されているが、少し気になって復習がてら「ハードウェアのメモリコンシステンシとは何なのか」について調査を行ったのでメモする。

参考文献

Computer Architecture, Sixth Edition: A Quantitative Approach (The Morgan Kaufmann Series in Computer Architecture and Design)

Computer Architecture, Sixth Edition: A Quantitative Approach (The Morgan Kaufmann Series in Computer Architecture and Design)

ヘネシー&パターソン コンピュータアーキテクチャ 定量的アプローチ 第5版

ヘネシー&パターソン コンピュータアーキテクチャ 定量的アプローチ 第5版

高性能コンピュータ技術の基礎

高性能コンピュータ技術の基礎

yohhoy.hatenablog.jp

メモリコンシステンシモデルが必要な状況

例えば、以下のような状況を考えたとき、2つのプロセッサはどのような動作をするだろうか。

f:id:msyksphinz:20180615020750p:plain

キャッシュの存在しない状態で、メモリの書き込みとメモリの読み込みがプログラムの順番通りに行われる場合、最後のB==0は不成立で、A==0も不成立となるだろう。

しかし、キャッシュが存在しておりキャッシュの中身をWriteInvalidateするようなケースでは時間軸が互いにずれてしまい、上記のように互いに必ず不成立になるという状態はありえなくなる。 また、プロセッサの高速化によりMEM[B]の読み込み動作がMEM[A]の書き込み動作を追い越すような場合、上記の前提は成立しなくなる。

厳密にメモリアクセスの順序を守ればいいのではないか?

基本的にはその通り。この、すべてのメモリアクセスの順番を守るメモリモデルのことを「シーケンシャルコンシステンシ」と呼ぶ。

しかしこのシーケンシャルコンシステンシに基づいているアーキテクチャでは、厳密にメモリアクセスの順番を守るために非常に性能が落ちるという問題がある。

そこで、ある程度であればメモリアクセスの順番を入れ替えてもよい、というのが、シーケンシャルコンシステンシ以外のメモリコンシステンシモデルである。

誰がメモリコンシステンシを守るのか

プロセッサの種類(プロセッサーアーキテクチャ)によって守るべきメモリコンシステンシモデルは異なっている。 例えば、ARMやRISC-Vはほとんどメモリアクセスの順番を入れ替えてもよい仕様になっているが、SPARCは一定のメモリアクセスの順番を守らなければならない。

また、それぞれのアーキテクチャ向けのコンパイラは、個々のアーキテクチャのメモリモデルに応じてアセンブリを出力する必要がある。

制約を緩和したメモリコンシステンシモデル(リラックスコンシステンシモデル)

というわけで、シーケンシャルコンシステンシでは十分に性能を出すことができないため、もう少し制約を緩和してもいいんじゃないの?というメモリモデルが存在する。 それらについて紹介するとともに、代表的なプロセッサアーキテクチャを列挙していく。

ここでは、Write(W)→Read(R)という表現を使い、W→Rは、Wが実行された後にRが実行されなければならない、ということを意味する。

  1. Total Store Ordering(TSO)もしくはプロセッサコンシステンシ : シーケンシャルコンシステンシに対して、W→Rのオーダリングを許可する。つまり、アセンブリの順番的にストア命令の後にロード命令が配置されているものを、順番を入れ替えてロード命令を先に発行してもよいという意味である。
  2. Partial Store Ordering(PSO) : シーケンシャルコンシステンシに対して、W→R, W→Wのオーダリングを許可する。つまり、アセンブリの順番的に2つ並んだストア命令を、逆の順序にメモリアクセスを行ってもよい、という意味である (ヘネパタ第5版は誤解を生みやすい表現なので注意!第6版が正しい)
  3. Weak Ordering : シーケンシャルコンシステンシに対して、すべての操作に対してオーダリングを許可する。
  4. Release Consistency : 考え方はWeak Orderingと同一だが、同期操作に対してオーダリングの制約が異なる。

以下はヘネパタ第6版からの流用(一部改変)。メモリコンシステンシ毎の動作の違いについて。

f:id:msyksphinz:20180615015236p:plain

こちらもヘネパタからの流用で、各プロセッサにおけるオーダリングの仕様について。

Model Used in Ordinary Ordering Synchronization Orderings
Sequential Consistency 殆どのプロセッサではオプション R→R, R→W, W→R, W→W S→W, S→R, R→S, W→S, S→S
Total Store Ordering or Processor Oreding IBMS/370, DEC VAX, SPARC W→R, R→W, W→W S→W, S→R, R→S, W→S, S→S
Partial Store Ordering SPARC R→R, R→W S→W, S→R, R→S, W→S, S→S
Weak Ordering PowerPC S→W, S→R, R→S, W→S, S→S
Release Consistency MIPS, RISC-V, Armv8, C, C++ S_A→W, S_A→R, R→S_R, W→S_R S_AS_A, S_AS_R, S_RS_A, S_RS_R

難しいのはWeak OrderingとRelease Consistencyの違いなのだが、どうも同期操作に対してRelease Consistencyの方が順序が少しだけ緩い。

ここで、"S"というのは同期操作を意味し、より厳密にはtex:S_Rtex:S_A に分類できる。 Weak Orderingでは、すべての同期操作に対して、R/WのどちらもSの前後で完全に実行を完了しなければならない。 しかし、Release Consistecyは

  • Acquire(S)後のWrite/Readの順番は守るべき(S_A→W, S_A→R)、しかし、Release(S)後のWrite/Readは守らなくてもよい(つまり、Release前に次のRead/Writeを出してもよいS_R→W, S_R→R)。
  • Read/Write後のRelease(S)の順番は守るべき(R→S_R, W→S_R)、しかし、Read/Write後のAcquire(S)の順番は守らなくてもよい(つまり、Read/Writeの前にAcquireを出してもよいR→S_A, W→S_A)。

という意味があり、Weak Orderingよりも少し制約が緩いものになっている。