未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

HyperThreadingとキャッシュミス。

米田Blog(SQL Server MEMO)さんからトラックバックをいただく。http://blogs.sqlpassj.org/yoneda/archive/2005/11/23/14983.aspx HyperThreading(以下HTと記す)とキャッシュミスの事に付いて考えてみる。あくまで自分の脳内俺様理解なのでちゃんとベンチマークをしてその仮説を一つ一つ検証しないといけないのだが現時点での俺様理解(仮説)を記すことは思考実験としてあながち無駄ではないと思うのでつらつら記す。
まづ発端となったCNETの記事。http://japan.cnet.com/news/ent/story/0,2000047623,20091397,00.htm?ref=rss(日本語訳)http://news.com.com/2100-1006_3-5965435.html(英語のオリジナル)その記事からリンクされているblog http://blogs.msdn.com/slavao/archive/2005/11/12/492119.aspx

Intelのハイパースレッディング技術により、論理プロセッサがL1およびL2キャッシュを共有する。これにより、L1およびL2キャッシュの内容が廃棄されることが考えられる」(Ocks)

HTでは一つの物理プロセッサには複数(通常は2つ)の論理プロセッサが実装され、L1(一次)およびL2(二次)キャッシュが共有される。そして各論理プロセッサで独立にスレッドが実行するので、最悪スレッド間でキャッシュの奪いあいが発生し、キャッシュコンフリクトにより性能が極度に低下する場合がある。
SMPでも同様なことが起こりそうであるが、通常はL1/L2キャッシュは共有しないのでHTでのような事は発生しない。キャッシュを共有するようなアーキテクチャであれば同様なことが発生するかもしれない。
copy_from_user_ll()の時のようなcache pollutionとHTで観測されるキャッシュコンフリクトは何が同じで何が異なるのか?キャッシュを奪いあって、有効なキャッシュを捨ててしまうという意味ではまさにcache pollutionである。当該Blogで紹介されている例は、SQL Serverには二つのスレッドがあって、worker thread と system threadというらしい、worker threadはクライアントからのリクエストを実行し、system thread はシステムのタスクを実行する。system threadの例としてlazywriterというのがあって、バッファをスキャンしてLRUにしたがってバッファを書き込むみたいなことをするらしい。一方のスレッドがシーケンシャルスキャンな場合は典型的なcache pollutionといえよう。シーケンシャルスキャンは条件が一致するまでデータをせっせと捨て去る(すなわち時間的局所性がない)から、最後のデータ以外はキャッシュに載せる必要は無い。最後のデータは条件が一致したものだから多分何らかの形で利用されるので時間的局所性があるのでキャッシュに載せておいたほうがいいかもしれない。(がどうやってあらかじめ判断するのだろう?)
シングルCPUでマルチスレッドアプリケーションでももちろんキャッシュコンフリクトは発生するが、通常スレッドの切替えは数万とか数十万クロックとか毎に発生するのでまあコンテキストスイッチのコストに比べればしょうがない。一方HTの場合はスレッドの切替えは1クロック毎なので他のスレッドに与える影響は非常に大きい。
oprofileかなんかでキャッシュミスイベントを測定すれば、コンフリクトしているスレッドに多くのキャッシュミスを発見できると思う。そのような競合するスレッドを発見できたとしよう。問題はそのような競合を発見したとしてそれをどのように解消できるか?現時点での解決策はHTを無効化するという非常に後ろ向き(?)の解決策しか知られていないことである。(これ本当かなあ?ひょっとして簡単に解決できる方法があるのにわたしがしらないだけかもしれない)
http://www.intel.co.jp/jp/developer/technology/itj/2002/volume06issue01/art06_computeintensive/p07_memory.htm

ハイパースレッディングテクノロジではキャッシュが共有されますが、これはアプリケーションの特性によってはパフォーマンスを向上させることもあれば、逆に低下させることもあります。(中略)このため、各論理プロセッサが利用できるキャッシュのサイズは本来の1/2になることが予想されます。

もちろんインテルの技術者はこの問題を正しく認識している。でもどうやって解決するのだろう?
これを解決するには、oprofile等によってRDBMSのキャッシュに対するビヘイビアを精密に調査する。分析する。解析する。どのようなメカニズムでキャッシュコンフリクトが発生しているか正確に理解する。問題を正確に理解しないことには解決策を作ることはできないのである。皆様の御知恵を拝借したい。というわけでオチの無い日記になってしまったが、HT aware RDBMS patchなるものがそのうちできるかもしれない。(希望的な観測)