これはまさにあなたの質問に対する答えではありません。とにかく、@Klas は
<ブロック引用>スレッドの実行時間が長すぎると、意図しないコンテキスト スイッチが発生します
だから私の考えは、スレッドの実行時間が長すぎることを確認できるということです。 perf を使用して、コンテキスト スイッチが最も頻繁に発生するコード内の場所を見つけます。また、古いバージョンのプログラムと新しいバージョンの測定値を比較することもできます。
Perf (https://perf.wiki.kernel.org/index.php/Tutorial) にはイベント context-switches
があります .それを測定し、それが発生したスタックトレースを収集できます。これは、コンテキスト スイッチの測定の例です:
perf record -e cs -g -p `pidof my_test` sleep 5
そして、それらがどこで発生するかを確認します。たとえば、システムコールがまったくない無限ループを持つ C++ のプログラムがあります。すべてのスイッチの内容には、関数 my_thread_func
からの stracetrace があります :
perf report --stdio -g --kallsym=/boot/System.map-2.6.32-431.el6.x86_64
# Samples: 7 of event 'cs'
# Event count (approx.): 7
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .............................
#
100.00% my_test [kernel.kallsyms] [k] perf_event_task_sched_out
|
--- perf_event_task_sched_out
schedule
retint_careful
my_thread_func(void*)
反対に、これは多くのシステムコールを伴う無限ループを持つ C++ 上のプログラムの測定値です:
# Samples: 6 of event 'cs'
# Event count (approx.): 6
#
# Overhead Command Shared Object Symbol
# ........ ............... ................. .............................
#
100.00% my_test_syscall [kernel.kallsyms] [k] perf_event_task_sched_out
|
--- perf_event_task_sched_out
schedule
|
|--83.33%-- sysret_careful
| syscall
|
--16.67%-- retint_careful
syscall
スレッド/プロセスがブロックするシステム コールを行うたびに、自発的なコンテキスト スイッチが発生する可能性があります。
非自発的なコンテキスト切り替えは、ブロックするシステム コールを行わずにスレッドが長時間 (通常は 10 ミリ秒程度) 実行され、CPU を待機しているプロセスがある場合に発生します。
あなたのプログラムは以前よりも CPU を集中的に使用しているようです。マルチスレッド化した場合、おそらく増加が予想されます。
821 コンテキスト スイッチ - プログラムの実行時間に応じて、これは多くない場合があります。
コンテキスト スイッチの数を減らしたい場合は、ワーカー スレッドの数を減らして、CPU コアよりもスレッド数を減らすことができます。
更新
どちらの場合も負荷が同じであると仮定すると、コードの変更により CPU 使用率が増加したように見えます。負荷の増加が懸念される場合は、コードを分析してボトルネックを見つける必要があります。インストルメンテーションは、コードのどの部分が問題を引き起こしているかを特定するのに役立ちます。