マルチプロセス/マルチスレッドC++アプリケーションのスケーリングで奇妙な動作が発生しています。アプリケーションには10個の個別のプロセスが含まれ、 nix Domain Sockets を介して通信し、各プロセスには最大100個のスレッドがIO)を実行し、そのIOでいくつかのプロセスがあります。システムはOLTPおよびトランザクションプロセス時間は重要です。IPC IOは、UNIXドメインソケット上でzmqを使用したブーストシリアル化に基づいています(高速です)ローカルサーバー上のすべてのベンチマークで十分です。24コアの2つの古いUNIXです。これで、コアの数が多いシステムでは、パフォーマンスがめちゃくちゃ低くなります。
1xIntel®Xeon®X5650-仮想-6コア-TPSは約150(予想)
1xIntel®Xeon®E5-4669v4-専用-32コア-TPSは約700(予想)
2xIntel®Xeon®E5-2699v4-専用-88コア-TPSは〜90(〜2000である必要があります)
3番目のサーバーでいくつかのベンチマークを実行すると、完全に正常なプロセッサー能力が示されます。メモリ帯域幅と遅延は正常に見えます。
htopは、カーネルで非常に高い時間を示しています(赤い部分)。したがって、最初の推測では、一部のシステムコールの実行に時間がかかりすぎるか、マルチスレッドコードで何か問題が発生しました。 (下の図を参照)perf top
は、特定のシステムコール/カーネルルーチン(native_queued_spin_lock_slowpath
)がカーネル時間の約40%を占めることを報告します(下の画像を参照)。
しかし、さらに別の非常に奇妙な観察はこれです:
したがって、taskset -cp 0-8 service
を使用してプロセスを実行すると、最大400TPSに達します。
割り当てられたCPUの数を88から8に減らすと、システムの実行速度が5倍速くなり、88コアで期待されるパフォーマンスの1/4になる理由をどのように説明できますか?
追加情報:
OS:Debian 9.0 AMD64
カーネル:4.9.0
複数のソケットがパフォーマンスを大幅に低下させる場合、確かにNUMA効果のように見えます。
perf
は非常に便利です。すでにパフォーマンスレポートで、native_queued_spin_lock_slowpath
が35%を占めていることがわかります。これは、同時実行コードにとって非常に大きなオーバーヘッドのようです。トリッキーな部分は、並行性コードを非常によく知らない場合に、何が何を呼んでいるのかを視覚化することです。
私はお勧めします システム全体のCPUサンプリングからフレームグラフを作成する 。クイックスタート:
git clone https://github.com/brendangregg/FlameGraph # or download it from github
cd FlameGraph
perf record -F 99 -a -g -- sleep 60
perf script | ./stackcollapse-perf.pl > out.perf-folded
./flamegraph.pl out.perf-folded > perf-kernel.svg
結果のグラフィックで、最も高い「高原」を探します。これは、最も排他的な時間を持つ機能を示します。
bpfcc-tools
パッケージがDebian安定版になったら、これらの「折りたたまれた」スタックをより少ないオーバーヘッドで直接収集できるようになることを楽しみにしています。
これで何をするかは、見つけたものによって異なります。どのクリティカルセクションがロックによって保護されているかを把握します。最新のハードウェアでのスケーラブルな同期に関する既存の調査と比較してください。たとえば、 同時実行キットのプレゼンテーションでは、スピンロックの実装が異なればプロパティも異なることに注意してください 。
これはハードウェアの「問題」だと思います。 IOサブシステムをオーバーロードすると、パラレリズムが増えるとディスクのように遅くなります。
主な適応症は次のとおりです。
ソフトウェアメーカーは、ほとんどの場合、マルチコアの最適化を行うのが面倒だからです。
ソフトウェア設計者は、システムの完全なハードウェア機能を使用できるソフトウェアを設計することはめったにありません。非常によく書かれたソフトウェアの中には、コインマイニングソフトウェアが良いと見なすことができます。それらの多くは、ビデオカードの処理能力を最大レベル近くで使用できるためです(ゲームとは異なり、ゲームの真の処理能力の利用に近づくことはありません。 GPU)。
同様のことが、今日のかなり多くのソフトウェアに当てはまります。マルチコアの最適化をわざわざ行うことはないため、ソフトウェアを実行すると、低速のコアに比べて高速に設定されるコアが少なくなり、パフォーマンスが向上します。より多くのより高速なコアの場合、同じ理由で常に利点になるわけではありません。コードの記述が不十分です。プログラムは、サブタスクを非常に多くのコアに分割しようとしますが、実際には全体的な処理が遅れます。