私のプログラムには、プロセスで始まり、プログラムが終了するまで残っているいくつかのスレッドがあります。アプリケーションの寿命の間にさまざまな負荷が発生し、時にはすべて100%で動作することがあります。
デフォルトでは、Linuxスレッドスケジューラはマルチコアシステムでこれらのスレッドの好みを非常に急性に変更します(IMO)。グラフィックプロセスモニター(gnomeのモニター)でバウンスチャートを見ると、これが一種のオーバーヘッドを構成するとは思えません。
編集する:明らかに、非常に安定した負荷の場合でも、スレッドは他のコアに予約されており、画像には表示されていなくても、各スレッドに対して選択されたコアがしばしば「交換」されることは非常に明らかです。
これらの好みの継続的な変化はパフォーマンスに悪影響を与えませんか?
それでは、なぜこのように実装されますか?好みを変えるとどんなメリットがありますか?
私の推測は次のとおりです
- ウェアレベリング - 1つのコアにすべての作業を集中しないでください
- 意図しない - 一部のスマートアルゴリズムは負荷に基づいて使用量を最適化しようとしますが、好みを変更する代わりにメンテナンスを保証するのに十分なオーバーヘッドはありません。
答え1
1つのコアですべてのスレッドを実行するには、より安価なシングルコアハードウェアを購入してください。
スケジューラは、すべてのコアの使用率を最大化しようとします。これは、空き時間があるすべてのコアにスレッドを派遣することを意味します。あるコアから別のコアにスレッドを移動するのにかかる費用は少ないため、スケジューラはこれを回避しようとします。しかし、通常、コアをアイドル状態にしないという利点は、スレッド移行コストよりもはるかに大きいため、これを大きく認識しません。これは、スレッドがコアローカルキャッシュよりも多くのメモリを使用する場合に特に当てはまります。スレッドが使用するメモリがコアローカルキャッシュにない場合、それを別のコアに移行しても不利益はありません。
Linuxのスケジューラなどの強力なスケジューラの事後評価は、パフォーマンスを低下させることがよくあります。
表示されるグラフは、個々のコアの負荷がいっぱいではなく少しずつ異なることを示します。おそらく、システム全体がCPUパフォーマンスではなく、現在実行中のジョブによってI / Oが制限されているからです。スレッドがあるコアから別のコアにどのくらいの頻度で移動するかについては、どのようにも言わない。
答え2
ここで提供されるスナップショットは、カーネルの種類(バージョン)によって異なります。以前のカーネルバージョン2.4では、親和性が悪く、システムのパフォーマンスに影響を与えるスレッドのピンポン移動が多く発生します。 2.5から始まるカーネルバージョンは比較的優れた親和性を持っています。
マルチコアベースのシステムでは、アフィニティ設定は、コア間でスレッドを移動する際のキャッシュの無効化を防ぎ、パフォーマンスを向上させることができます。
Linuxベースのマルチコアシステムでは、アプリケーションの種類/要件に応じて、プロセスの場合はsched_setaffinity/taskset、スレッドの場合はpthread_setaffinity_npを使用して、スケジューラのアフィニティ動作(自然のアフィニティ)を上書きできます。
カーネルシャークマルチコアシステムとの類似性を視覚的によく表現するようです。
また注意事項トップアフィニティ設定(スケジューラオーバーライド)の視覚的なサポートを提供します。