梅澤威志 twitter: @umezawa_takeshi 隣の芝は茶色いか 梅澤威志 twitter: @umezawa_takeshi
NUMA って 知ってますか
Non- Uniform Memory Access
不 均一な メモリ アクセス
NUMA とは マルチプロセッサシステムにおいて、メモリ(要するにDRAM)へのアクセス(スループット、レイテンシ)が均一でないような環境
もうちょっとわかりやすく プロセッサから見て「近いメモリ」と「遠いメモリ」があり、どのメモリが近いかはプロセッサによって異なる環境のこと どのメモリが近いかがプロセッサによらず同じであるような環境は、単にメモリ階層が存在しているだけ
つまりこういうこと プロセッサ プロセッサ 遠い 近い 近い メモリ メモリ
具体的な製品 最近だと PC でもマルチプロセッサシステムは全部 NUMA である Intel だと Nehalem の Xeon (2009) 以降 AMD だと Opteron (2003) 以降
最近のPCのNUMAの図 メ モ リ CPU CPU メ モ リ I/O
ここから 本題
昔こんなこと言ってました https://twitter.com/umezawa_takeshi/status/724997040715898881 でも実は測ってない(=伝聞)
どうやって測ろう ストアのレイテンシを測るのは難しい ロードのレイテンシを測ろう いつ完了したのか知る方法がない ロードのレイテンシを測ろう ロードして、それが終わったらまたロードして…をたくさん(10秒ぐらい)繰り返す 経過時間 ÷ ロード回数 = レイテンシ
それほど単純ではない(1) 最近のプロセッサはスーパースカラ&アウトオブオーダーなので、単にロード命令を並べただけでは並列に実行されてしまう 並列に実行されないように、ロードしたらアドレスが取れて、そのアドレスからロードしてアドレスが取れて…という構造にする(ロード間に依存関係を発生させることで直列に実行させる)
それほど単純ではない(2) 最近のプロセッサはハードウェアプリフェッチがあるので、規則正しいメモリアクセスを行うと勝手にアクセスしてキャッシュメモリまで持ってきてしまう アクセスするアドレスがランダムになるようにして、ハードウェアプリフェッチが効かないようにする
それほど単純ではない(3) 隣のキャッシュのデータをロードしたら自分のキャッシュにコピーができてしまう(たぶん) 諦めて隣のメモリのレイテンシを測って、自分のメモリのレイテンシとの差で推測する
測定ツール https://github.com/umezawatakeshi/numa_memory_latency 後述の機材が CentOS 6 で動いている関係上、 GCC 4.4.7 の C++0x の範囲で記述。(C++11 でも OK)
測定機材 Dual Xeon E5-2630L v2 たまたま手の届く範囲にこれがあっただけ Ivy Bridge EP 6C12T Base 2.4GHz, TB 2.8GHz L1D$: 32KiB/core L2$: 256KiB/core L3$: 15MiB/socket たまたま手の届く範囲にこれがあっただけ
測定上の注意 このハードの管理者ではないので、 このホストを占有できてはいないので、 非常にザックリした測定であることに注意 サーバとしての製品名は知らない EIST や TB や HT などをオフにすることもできない このホストを占有できてはいないので、 他のプログラム(特にデーモン)が全く走っていない状態で計測できているわけではない 非常にザックリした測定であることに注意
~1.6ns ~7.0ns ~18ns ~90ns ~190ns 測定結果 対象 レイテンシ L1キャッシュ (32KiB/core) L3キャッシュ (LLC) (15MB/socket) ~18ns ローカルノードの メインメモリ ~90ns リモートノードの ~190ns
結論 隣のメモリは遠い というか隣のプロセッサが遠い NUMAシステムで、複数のプロセッサにまたがってメモリをたくさん使うタスクを適切に書くのは難しいです
オマケ:よく分からないこと L1 のレイテンシは CPU0 より CPU1 の方が小さかった L2 のレイテンシは計測誤差程度だった 何回測っても同じ傾向になる 計測手法に若干の問題がある可能性…?