Ce n'est pas exactement une réponse à votre question. Quoi qu'il en soit, @Klas souligne que
Un changement de contexte involontaire se produit lorsqu'un thread s'exécute depuis trop longtemps
Donc, mon idée est que vous pouvez vérifier ce que vos threads durent trop longtemps. Utilisez perf et trouvez les endroits dans votre code où les changements de contexte se produisent le plus souvent. Et éventuellement comparer les mesures de l'ancienne version de votre programme avec la nouvelle.
Perf (https://perf.wiki.kernel.org/index.php/Tutorial) a l'événement context-switches
. Vous pouvez le mesurer et collecter des stacktraces là où cela se produit. Voici un exemple de mesure des changements de contexte :
perf record -e cs -g -p `pidof my_test` sleep 5
Et puis vérifiez où ils se produisent. Par exemple, il existe un programme en C++ avec une boucle infinitive sans aucun appel système. Tous les contenus du commutateur ont stracetrace de ma fonction 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*)
Au contraire, c'est une mesure pour un programme en C++ qui a une boucle infinitive avec beaucoup d'appels système :
# 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
Un changement de contexte volontaire peut se produire chaque fois qu'un thread/processus effectue un appel système qui bloque.
Un changement de contexte involontaire se produit lorsqu'un thread a fonctionné trop longtemps (généralement quelque chose comme 10 ms) sans effectuer d'appel système qui bloque et que des processus attendent le processeur.
Il semble que votre programme soit plus gourmand en CPU qu'avant. Si vous l'avez rendu multithread, une augmentation est probablement attendue.
821 changements de contexte - selon le temps d'exécution de votre programme, cela peut être beaucoup ou pas.
Si vous souhaitez réduire le nombre de changements de contexte, vous pouvez réduire le nombre de threads de travail afin qu'il y ait moins de threads qu'il n'y a de cœurs de processeur.
Mettre à jour
En supposant que la charge est identique dans les deux cas, il semble que les modifications du code aient augmenté l'utilisation du processeur. Si l'augmentation de la charge est un problème, vous devez analyser le code pour trouver le goulot d'étranglement. L'instrumentation peut être utile pour isoler quelle partie du code est à l'origine du problème.