このページの本文へ

Haswellで導入された新機能「TSX」とは? IDF 2012より

2012年09月18日 22時20分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

 ロックをかけられたメモリーは、アンロックされるまでは他のスレッドからの書き込みを禁止されるので、これにより書き換えを防ぐ方法だ。これには、一定のメモリー範囲をまとめてロックする場合(Coarse grain Lock、粗粒度ロック)と、特定のアドレスだけなど狭い範囲をロックする場合(Fine grain Lock、細粒度ロック)の2種類がある。

 前者は多くのスレッドに影響を与えやすい問題があるし、後者は2つのスレッドがお互いに必要なメモリーをロックしてしまい、処理が進まなくなる「デッドロック」を発生させる可能性がある。デッドロックは2つのスレッドのほんのわずかなタイミング違いで簡単に発生してしまうため、制御することが困難で、プログラム開発を困難にしてしまう。そのため通常は、他のスレッドに影響が出ることを覚悟の上で、広い範囲をロックする方法をとることが多い。

 もうひとつの対処方法は、並列に処理を行なわせる一方で、あるスレッドが読んだメモリーアドレスに他のスレッドが書き込んだことを検出して、処理を失敗させて最初からやり直す方法だ(図3)。これを「トランザクション」処理という。

図3 銀行口座の例で見るトランザクションによる処理やり直しの仕組み

 トランザクション処理は銀行業務などのように、複雑でかつ間違いが許されないような処理に利用される。これまでは主に、データベースの更新などに利用されてきた技術だ。

 メモリーのロックは、基本的にCPUが提供する機能を利用するが、すでにロックされている対象メモリーに対して他のスレッドがロックしようとすると、アンロックするまで待たされてしまう(実際にはアーキテクチャーによって異なるが)。またCPUの提供するロック機構は、アセンブラレベルで記述する必要があるため、通常はOSが提供する「セマフォ」や「ミューテックス」と呼ばれる機構を使って、メモリーロックと同等の処理をする。しかしこのセマフォやミューテックスの処理自体にも、メモリーロックが含まれる。

 一方トランザクション処理は、ソフトウェアだけで実現しようとすると、プログラムが複雑になってしまうという欠点がある。TSXはこうした問題を解決するために作られた機構だ。

TSXのトランザクション処理

図4 銀行口座の例で見るTSXでのトランザクション処理

 TSXの基本的な動作は、トランザクション処理にある(図4)。トランザクション処理をソフトウェアで行なおうとすると、コミット※1前に対象が書き換わっていないかどうか(コンフリクトの検出)の処理が煩雑になる。チェックの対象が多数ある場合、すべてが一致しているかどうかを確認しないと、コンフリクトの有無を検出することができないからだ。
※1 トランザクションの終了処理。TSXの場合は、データの書き込み、1次キャッシュの始末、TSXの終了など。

 TSXでは「コンフリクト」のチェックを自動で行なう。TSXの機能のひとつである「Restricted Transactional Memory」(RTM)には、トランザクションの開始と終了を示す「XBEGIN」「XEND」という命令がある。この命令で挟まれている部分(トランザクション対象ルーチン)では、TSXのトランザクション機能が働く。トランザクションの開始となるXBEGIN命令を実行すると、その時点でのCPUの内部状態がCPU内の特別な場所に保存される(図4の左右処理フロー冒頭)。

 トランザクション対象ルーチンからのメモリー読み出しは、コンフリクトの監視対象となる。これには1次(L1)キャッシュを使う(メモリーからの読み込みは必ず1次キャッシュにキャッシュされる)。同様に、メモリーへの書き込みは1次キャッシュのテンポラリー(一時利用)領域に置かれて、トランザクション処理が終わるまで書き込みを保留される。

 この最中に、読み出したメモリーアドレスを他のスレッドが書き込むと(コンフリクトの発生)、トランザクション開始時に指定したアボート・アドレスにあるプログラム(アボート・ルーチン)に制御が移る。このときCPUの状態はトランザクションを開始した時点に戻されるが、EAXレジスタは例外で、ここにアボートの理由を示す番号が置かれるほか、XABORT命令(強制的にアボートを引き起こす)の引数などが入る。

 また、1次キャッシュに保存された書き込みデータは破棄される。単純なコンフリクトなら、このアボート・ルーチンでトランザクションの開始位置からプログラムを再実行させる。

 TSXでは、コンフリクトが発生しなければアボートも発生せず、そのままXENDで1次キャッシュに保留されていたメモリー内容がコミットされ書き込まれる。「コンフリクトが生じなければ、そのまま処理を続ける」というやり方を、「楽観的な実行」と呼ぶ。実際の処理では読み書きするメモリーは多数あるし、広い範囲をロックして利用することになるため、常に衝突が起きるとは限らない。

 しかしマルチプロセッサー環境である以上、処理に矛盾が生じないことを保証する必要がある。TSXのRTMは、このような処理に矛盾が起きないことを保証しつつ、実際に衝突が起こった場合にだけやり直すという方法で、実行を効率化するわけだ。実行の効率化は複数スレッドによる衝突の可能性(発生頻度)に依存し、プログラマーは、その可能性を考慮してRTMを利用する必要がある。

カテゴリートップへ

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン