IntelのMESIFプロトコル

コモンバスの一種であるフロントサイドバス(FSB)を使っていた時代には、IntelはMESIプロトコルを使っていた。MESIプロトコルでは、リードアクセスがプライベートキャッシュをミスした場合は、他のコアにModifiedデータを持っている場合にはメモリに書き戻せというコマンドを放送する。そして、書き戻しの有無に関わらず、メモリからデータを読み込む。

しかし、他のコアのキャッシュにはModified状態のキャッシュラインは無いが、 Exclusive、あるいはShared状態のキャッシュラインがある場合は、そこからデータを送ってもらう方がメモリからの読み出しよりアクセス時間が短くて済む。Exclusiveのキャッシュラインは1つしか存在しないので問題はないが、Sharedのキャッシュラインは同じ内容のものが複数のコアのキャッシュに存在し得るので、どのコアのキャッシュがデータを送るかということが問題になる。この問題に対して、Intelは、MESIにForwardingという状態を付け加えた「MESIF」というプロトコルを考案した。Forwarding状態は、データはメモリのデータ値から変更されておらず、かつ、他のキャッシュにも同じデータが存在しうるという点でShared状態と同じであるが、読み込み要求の放送に対してはForwarding状態のキャッシュが応答し、Shared状態のキャッシュは応答しないという点が異なる。つまり、Shared状態の複数のキャッシュラインの中から1つの代表選手を決め、それをForwarding状態とする。そして、データの読み込み要求に対しては、この代表選手が対応するというわけである。

図3.12 MESIFプロトコルでは、同一データが他のコアのキャッシュラインに存在する場合は、メモリでなく他のコアのキャッシュからデータを転送する

P0のリードがプライベートキャッシュをミスすると、(1)で他のコアへの問い合わせを放送する。そのとき、Forwarding状態のキャッシュラインを持っているPiは(2)で「データを持っているので供給する」と応答し、Shared状態のPjは(3)で「供給しない」と応答する。応答集約機構は、これらの応答をまとめて(4)で要求元のP0に送る。

そして、(5)で「データを持っているので供給する」と応答したPiからキャシュラインのデータを転送する。このとき、Forwarding状態であったキャッシュラインは代表を外れてShared状態となり、新たにデータを受け取ったキャッシュラインが代表選手のForwarding状態となる。代表選手を固定すると、同じキャッシュがいつもデータ供給に応じるという負荷の不均衡が起こるので、このように代表選手を次々と変える方が良い。また、キャッシュラインの入れ替えはLRU(Least Recently Used)のような方法で行われるので、古いキャッシュラインと比べて新しいキャッシュラインの方が追い出される確率が小さく、代表選手のキャッシュラインが追い出されて居なくなってしまうというリスクも小さくなる。

問い合わせに対して、Modified状態のキャッシュラインをメモリに書き出すのと、どのコアにもそのアドレスのキャッシュラインが無い場合は、メモリからデータを読みExclusive状態とするのは、元となっているMESIプロトコルと同じである。また、問い合わせに対してExclusiveのキャッシュラインを持つコアがある場合は、そのコアがデータを供給し、キャッシュラインの状態をSharedに変更する。

なお、Forwarding状態のキャッシュラインを持つコアとShared状態のキャッシュラインを持つコアがあり、Forwarding状態の方のキャッシュラインが他のアドレスのデータを格納するために追い出された場合は、Shared状態のキャッシュラインが残ってしまう。この場合は、第3のコアからの読み出しに対してはShared状態のキャッシュラインはデータを供給しないので、メモリからデータを読み出すことになると思われる。これは性能的には最適ではないが、データ値は同じであるので、動作としては問題ない。しかし、他のコアのキャッシュに同一アドレスのデータがあるので、メモリからデータを読んだからと言って、そのキャッシュラインの状態をExclusiveにすることは出来ない。このため、Forwarding状態であるのでデータを供給する、Sharedを持っている、そのアドレスのキャッシュラインは持っていないというように応答を拡張しているのではないかと思われる。