アプリケーション from 詳解システム・パフォーマンス
avashe.icon5章 アプリケーション
配列を使ったハッシュテーブルの並行化のために、各bucketsにロックを持たせる
両極端の間でバランスをとる
テーブル全体に1ロックだと競合がありすぎてレイテンシが大きい
要素ごとだとデータ構造作成、破棄のためにCPUオーバヘッドが大きくなる
bucketsはハッシュ関数で参照できるエントリのことで、ハッシュが被ったときはよくそこから線形リストにする領域
いずれかのロックが読まれるとキャッシュラインに複数のロックが乗る
ロック1つを切り替えるごとにそれ以外のキャッシュライン上のロックが不整合になり、キャッシュコヒーレンシのオーバヘッドが伸びる
連続するロックの間にバイトをパディングし、個々のキャッシュラインに1ロックになるよう調整する
これ調整されたコード実際に読んでみたい
ノンブロッキングIO、微小なIOでスレッド作るなって話か
並行プログラミングというジャンルではあるが、むしろ大きい粒度に直列化するための技術
CPUバインドはバインド先を決める仕組みを調整しないとマルチテナント環境では事故を起こす
プログラミング言語のチューニングについて
コンパイル最適化オプションは挙動が変わりうるので、デバック用情報を除いて最適化する系と併用しない
基本的に「チューニングして得られる速度」<「チューニングや障害対応の機会をもたらす可観測性の機能」なので、可観測性を落とす最適化オプションはおすすめしない
例えば: gcc -O3の-fomit-frame-pointerなど
使えるレジスタが増える代わりにスタックトレースをプロファイリングする機能が失われる
vm方式のプログラミング言語は最適化が一番難しい
JITが知られるように、環境に応じた翻訳や最適化が入るので可観測性の観点では最も難しい
vmのエコシステム、特に公式が出しているツールを使うしかない
GCあり言語だとGCアルゴリズムを理解してチューニングする必要がある
実際はアプリのアーキテクチャと不可分なので、パラメータいじってダメならアプリの開発者にコンサルすることになる
スレッドの状態の分析
状態の分類を定義して、それぞれの時間を分析、短縮する
本書では6種類を例示
実行中
CPU上
実行可能
スケジューラによるCPU時間の割り当て待ち
無名ページング
実行可能だが無名ページのページイン待ちでブロックされている
スリーブ
ネットワーク、ブロックデバイス、データ/命令のページインなどのIO待ち
ロック
同期ロックの獲得待ち
アイドル
ワークロードを待っている
定義した分類を計測して大きなものを更に詳細に分析する
実行中なら
ユーザーモードか、カーネルモードか調べる
プロファイリングによってCPUの消費理由を調べる
どのコードパスが何割消費しているかが分かる
実行可能なら
スレッドの生成され過ぎか、CPUリソースが足りていないか
リソース制限の見直しなど
無名ページングなら
メモリが足りていなかったり、何かがリークして圧迫している可能性
使用状況とリソース制限の見直し
スリープ
ブロックさせるリソースの解析(口述)
ロック
どのロックをどのスレッドが保持しているか、長期間ロックしているならそれは何故か
ロックの保持が他のロックを待っている可能性はないか
ロックやスリープはアイドル時間である可能性を念頭に掘り下げて調査
感想
5.2.5 並行/並列処理
Bucketsにロックを持つハッシュテーブルが気になった
バカ並列をちょうどいい粒度でスケジュールする方法を仕事で求めているので
false sharingの調整はどう実装するか
/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size がラインサイズ
処理系依存なアラインメントを把握しつつ、パディングサイズ決めるのつらそう