Intelの次世代Core「Haswell」のトランザクションメモリを読み解く(後編)

写真拡大

中編はコチラRead Set、Write Setはキャッシュライン単位の管理で、L1キャッシュで他のプロセサからのアクセスをチェックすると書かれている。

これを実現するためには、L1データキャッシュのタグを拡張する必要がある。

それぞれのキャッシュラインのタグにRead SetかWrite Setかの識別ビットを付け、かつ、それがどのトランザクション開始命令に対応するのかが判別できるようにする必要がある。

HaswellのTSXでは、トランザクション領域の中にトランザクション領域を入れ子にすることができるが、ハードウェア的には最も外側の1つのトランザクション領域として扱われるので、1つのL1キャッシュにはたかだか、HyperThreadの2つのトランザクションのRead Set、Write Setしか存在しない。

つまり、トランザクションを識別するID(TxID)としては、ハードウェアスレッド番号の0か1という1bitがあればよい。

そして、TxIDでインデックスされる2エントリのテーブルにトランザクション開始時のレジスタファイルの状態などのアーキテクチャ状態を記憶しておけば、アボート時にはこれを読み出して、トランザクション開始命令の直前の状態に戻すことができる。

そして、トランザクションを実行中のコアからのキャッシュアクセスに対しては、Readアクセスがヒットすれば、タグのRead Setビットをセットし、そのトランザクションのTxIDを記憶する。

また、Writeアクセスであれば、まず、他のすべてのキャッシュにWriteback-Invalidate要求を送り、最新のデータを持っているキャッシュからメモリに書き戻し(Writeback)、そのアドレスのデータを持つキャシュには、Invalidにするよう要求(Invalidate)する。

これは、通常のストアの場合と同じ処理である。

そして、他のプロセサのキャッシュがInvalidateされてそのデータを持っていない状態になると、自分のL1キャッシュにWriteデータを書き込みModified状態にする。

このとき、タグのWrite Setビットをセットし、TxIDを記憶する。

Readアクセスの場合、それがWrite Setのラインであれば TxIDもタグマッチングに含め、書き込みを行ったトランザクションだけがキャッシュヒットして、Write Setのデータを読めるようにする。

なお、他のコアからのアクセスに対しては、TxIDはマッチしないようにしておく。

TxIDがマッチしないアクセスが来た場合は、他のスレッドがWrite Setを読もうとしているので、干渉を起こさないように、実行中のトランザクションをアボートする。

他のソケットのプロセサコアからのスヌープは、L3キャッシュ(Intelの用語はLLC)が、そのチップ内のキャッシュにそのアドレスのキャッシュラインがあるかどうかを判断するので、書き込み権を得るためのWriteback-Invalidateに対して、L3キャッシュのラインのデータ自体はInvalidであるが、チップ内のどのコアにはInvalidでないデータが存在する可能性があり、スヌープを送る必要があるという情報をタグに保持する。

マルチコア共通のL3キャッシュは、 HTMサポートとは関係なく、この機能を持っている筈である。

L3キャッシュは、この情報を使って、チップ外からのスヌープをRead Set、Write Setを管理しているコアのL1キャッシュに送る。

この要求を受け取ったL1キャッシュはRead Set、Write SetのビットがセットされたラインへのWriteアクセス、あるいは、Write SetのビットがセットされたラインへのReadアクセスが検出されると、そのTxIDのトランザクションをアボートする。

トランザクションをアボートすると、Read Setビットをリセットし、Write SetのビットをリセットしてラインをInvalid状態にする。