Что означает "высокий непроизвольный контекст"?
У меня есть переписанная часть кода в C. При тестировании ее с протоколированием использования ресурсов с помощью getrusage (2) API API.
Перед изменением кода:
user time (ms): 21503
system time (ms): 372
involuntary context switches: 20
После изменения:
user time (ms): 25589
system time (ms): 80732
involuntary context switches: 821
В коде, который я переписал, я вижу много involuntary context switches
.
Мой вопрос не в том, как уменьшить контекстные переключатели. Но..
- Что происходит, когда "принудительные переключатели контекста" больше?
- Каким образом это повлияет на систему?
P.S: На диске нет активности, поскольку ничего не записывается. Он просто пингует сервер несколько раз.
Update:
Добавлена система и время пользователя.
Программа многопоточная. В обоих случаях генерируется одинаковое количество потоков (поток 3k). Переписывается только базовый api в C.
Ответы
Ответ 1
Переключатель контекстного контекста может возникать всякий раз, когда поток/процесс блокирует системный вызов.
Неконтактный контекстный переключатель возникает, когда поток работает слишком долго (обычно что-то вроде 10 мс), не делая системный вызов, который блокирует, и есть процессы, ожидающие CPU.
Похоже, что ваша программа теперь больше, чем раньше. Если вы сделали его многопоточным, возможно, ожидается увеличение.
821 контекстные переключатели - в зависимости от времени выполнения вашей программы это может быть или не быть много.
Если вы хотите уменьшить количество переключателей контекста, вы можете уменьшить количество рабочих потоков, чтобы было меньше потоков, чем у процессоров.
Обновление
Предполагая, что загрузка в обоих случаях одинакова, похоже, что модификации кода увеличили использование процессора. Если повышенная нагрузка вызывает беспокойство, вы должны проанализировать код, чтобы найти узкое место. Instrumentation может быть полезным для выделения части кода, вызывающей проблему.
Ответ 2
Это не ответ на ваш вопрос. В любом случае @Klas указывает, что
Неконтактный контекстный переключатель возникает, когда поток запущен слишком долго
Итак, моя идея заключается в том, что вы можете проверить, что ваши потоки работают слишком долго. Используйте perf и найдите места в вашем коде, где чаще всего переключаются контексты. И, возможно, сравните измерения для старой версии вашей программы с новой.
Perf (https://perf.wiki.kernel.org/index.php/Tutorial) имеет событие context-switches
. Вы можете измерить его и собрать стоп-трассы там, где это происходит. Это пример измерения переключателей контекста:
perf record -e cs -g -p `pidof my_test` sleep 5
И затем проверьте, где они происходят. Например, есть программа на С++ с инфинитивным циклом без каких-либо системных вызовов. Все содержимое коммутатора имеет stracetrace из моей функции 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*)
Напротив, это измерение для программы на С++, которая имеет бесконечный цикл с большим количеством системных вызовов:
# 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