Toto není odpověď přesně na vaši otázku. Každopádně @Klas poukazuje na to
K nedobrovolnému přepnutí kontextu dojde, když vlákno běží příliš dlouho
Takže můj nápad je, že můžete zkontrolovat, jaká vaše vlákna běží příliš dlouho. Použijte perf a najděte místa v kódu, kde dochází nejčastěji k přepínání kontextu. A případně porovnejte měření staré verze vašeho programu s novou.
Perf (https://perf.wiki.kernel.org/index.php/Tutorial) má událost context-switches
. Můžete to měřit a sbírat stacktrace tam, kde se to děje. Toto je příklad měření kontextových přepínačů:
perf record -e cs -g -p `pidof my_test` sleep 5
A pak zkontrolujte, kde k nim dochází. Například v C++ existuje program s infinitivní smyčkou bez jakýchkoli systémových volání. Veškerý obsah přepínače má stracetrace z mé funkce my_thread_func
:
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*)
Naopak toto je měření pro program v C++, který má infinitivní smyčku se spoustou systémových volání:
# 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
K dobrovolnému přepnutí kontextu může dojít vždy, když vlákno/proces provede systémové volání, které blokuje.
K nedobrovolnému přepnutí kontextu dochází, když vlákno běží příliš dlouho (obvykle něco kolem 10 ms), aniž by provedlo systémové volání, které blokuje a na CPU čekají procesy.
Zdá se, že váš program je nyní náročnější na CPU než dříve. Pokud jste to udělali vícevláknovým, pak se pravděpodobně očekává nárůst.
821 kontextové přepínače - v závislosti na době provádění vašeho programu to může nebo nemusí být mnoho.
Pokud chcete snížit počet kontextových přepínačů, můžete snížit počet pracovních vláken, takže jich bude méně než jader CPU.
Aktualizovat
Za předpokladu, že zatížení je v obou případech totožné, vypadá to, že úpravy kódu zvýšily využití procesoru. Pokud je zvýšené zatížení problémem, měli byste analyzovat kód, abyste našli úzké místo. Přístrojové vybavení může být užitečné při izolování toho, která část kódu způsobuje problém.