一方、Includeフィルタはプロセサがキャッシュミスして新しいキャッシュラインを要求してキャッシュに格納した場合に、そのアドレスを記憶する。そして、記憶したアドレスと一致したスヌープ要求を実行させる。アドレスの記憶をキャッシュタグと同じにやればデュプリケートタグになるが、Includeフィルタの場合は、もう少し粗い簡単なやり方がある。

Includeフィルタの作り方であるが、テーブルのエントリをディレクトリのようにキャッシュラインアドレスごとに設けるのではなく、図9.15に示すようにアドレスを何らかの関数(図9.15ではアドレスを3分割してXORしている)でハッシュしてビット数を減らすことにより必要なエントリの数を大幅に減らすことができる。このようにすると、本来はAとBという異なるアドレスであってもハッシュしたら同じ値になるというケースがあり、アドレスAのデータを読み込んだプロセサに対してアドレスBのアクセスでもデータを持っていると判定されて無駄なスヌープが行われることになる。しかし、テーブルサイズがある程度大きければ、このような偽の重なりの確率は小さいので、実用上、十分である。

図9.15 ハッシュを用いるInclusionフィルタ

このハッシュを使うIncludeフィルタの場合は、キャッシュに入った可能性のあるアドレスが蓄積されていくので、容量に制限がないとしても、時間が経つにつれてフィルタ効率が低下してしまう。しかし、ハッシュにより複数の異なるアドレスが1つのエントリに重なっている場合があるので、単に、そのアドレスのキャッシュラインがインバリデートされたからといって、そのIncludeフィルタのエントリを削除することはできない。

このため、各エントリにカウンタを持ち、キャッシュに取り込まれた場合には+1し、インバリデートでキャッシュから消去された場合には-1して、カウントがゼロになったらIncludeフィルタからエントリを除去するという制御が行われる。

図9.16に示すNECのAzusAシステムは4個のItaniumチップのグループをセルと呼び、4個のセルを相互接続する16ソケットサーバである。どれかのプロセサでキャッシュミスが発生しスヌープ要求が出ると、この要求は全セルにブロードキャストされるが、各セルのSystem Address Controller(SAC)はスヌープフィルタをチェックし、該当するアドレスのキャッシュラインを持っている場合だけスヌープを実行し、キャッシュラインを持っていない場合は、各プロセサにスヌープを送ることなく応答を返すというInclusionフィルタ構造になっている。これにより、それぞれのItaniumチップとして処理が必要となる他のチップからのスヌープの回数を大幅に減少させている。

図9.16 スヌープフィルタを用いるAzusAのアドレス系の構造

また、図9.17に示すIntelのItanium 2プロセサ用のチップセットであるE8870も論理的にはAzusAと似た構造であるが、4個のItaniumチップを接続するScalable Node Controller(SNC)と4個のSNCと2個のIO Hubチップを相互接続する2個Scalability Port Switch(SPS)チップで構成され、最大16ソケット(論文では16ソケット構成であるが、Intelの製品ページでは最大8ソケットとなっており、16ソケット構成はサポートされていない)の中規模のサーバを実現できるようになっている。E8870では全プロセサからのメモリアクセス要求を集約するSNCにスヌープフィルタを設けているため、ブロックされるスヌープ要求はここで止まり他のグループに送る必要が無くなる。したがって、消費電力的にも有利であるし、アクセス時間的にも有利という構造になっている。

図9.17 E8870SPチップセットを用いた8ソケットシステム構成(IntelのWebページから転載)

このAzusAやE8870の構造は、アドレスコントローラ部分(E8870ではSPS)に4個のプロセサのキャッシュ状態を反映する大きなテーブルを持つ必要があるが、不必要なスヌープがあまり発生しないので、全プロセサにスヌープをブロードキャストするシステムより高いスケーラビリティーが得られる。

Nehalem以前のIntelプロセサは、FSB(Front Side Bus)と呼ぶコモンバスを用いており、ソケット数が多くなるとバスバンド幅が不足するため、Intel 5000系のチップセットでは、2本のFSBを出すという構成を採用した。そして、Intel 5000Xでは、このチップセット内に16MBのテーブルを持つスヌープフィルタを備えて、一方のFSBに乗ったスヌープ要求を他方に伝えるか、その必要が無いかを判定して、スヌープ回数を減らすという設計をとった。

しかし、バスのトラフィックがあまり多くない場合には、スヌープ回数を減らしても性能改善効果はなく、Intel 5000Xでは、逆にスヌープフィルタ処理を行う分だけメモリアクセスが遅くなるという弊害があり、スヌープフィルタなしのIntel 5000Pに比べて性能が低下するアプリケーションが続出したと言われている。このように、スヌープフィルタを用いる場合は処理のオーバヘッドを減らすことが重要であり、第2世代のスヌープフィルタを搭載する後継のIntel 7300系のチップセットでは、この問題は解決され、性能が向上するようになったとのことである。

また、AMDはIstanbulというコードネームで開発されてきた6コアのOpteronプロセサでHT Assistと呼ぶ構造を導入してスヌープを減らしたと発表している。この機構の詳細は不明であるが、6MBの3次キャッシュの内の1MB分をExport Directoryとして確保し、ここに自ノードから他のプロセサに輸出されたキャッシュラインの情報を記憶し、自ノードでのメモリアクセス時点でこのディレクトリをチェックし、キャッシュラインが輸出されたノードだけにスヌープ要求を送ると説明されている。ということで、Istanbulで使われているのは、一種のInclude構造のスヌープフィルタ方式と言える。

AMDの発表では、このHT Assist機構の採用により、4ソケットシステムでは、メモリバンド幅を測定するStreamベンチマークに関して約60%性能向上と述べられている。ただし、Streamベンチマークでは全部のメモリアクセスを自ノードのメモリに割り付けることができるのでスヌープがまったく発生しない状況とすることができ、AMDの主張は正しいのであろうが、この性能向上は、その他のアプリケーションではあまり存在しない理想的なケースでの性能改善の上限値であると考えられる。なお、2ソケットシステムではスヌープトラフィックが少なく、スヌープフィルタの性能改善効果よりも、3次キャッシュが6MBから5MBに減少することによる性能ロスの方が大きいので、この機構を使うかどうかをBIOSでの設定で選択することができるようになっている。