У нас есть процесс, который отвечает за опрос оборудования с интервалами, зависящими от времени. Мы хотели бы выделить ядро ЦП для этого процесса. Например, мы хотим, чтобы этот процесс оставался работоспособным в любое время.
Наша первая попытка решить эту проблему была следующей:
# Set process to highest priority
nice -n -20 cmd
# Set thread affinity in C for our hardware sampling thread
pthread_setaffinity_np(...)
Оба шага выше работают как и ожидалось. Наша нить остается там, core3
где мы ее установили, и nice
находится -20
наверху.
При повторном запуске ftrace
каксогласно этому обсуждениюиЭта проблема, мы обычно видим следующее:
> cat trace | grep " 3)" | grep " => "
3) rhd_loc-2735 => <idle>-0
3) <idle>-0 => rhd_loc-2735
3) rhd_loc-2735 => <idle>-0
3) <idle>-0 => rhd_loc-2735
3) rhd_loc-2735 => <idle>-0
3) <idle>-0 => rhd_loc-2735
rhd_loc-2735
это наш процесс.
В дополнение к тому, что показано выше, мы видим много случаев, когда kworker-2703
переключаются, а иногда и другие процессы с более низким приоритетом переключаются на ядро.
Мы считаем, что причина переключений контекста в том, что наш процесс взаимодействует с SPI
(Serial Peripheral Interface), который ожидает IRQs
, а также SPI
работает с тактовой частотой на порядок медленнее, чем ядро ЦП. Поэтому наш процесс проводит большую часть времени в ожидании SPI/IRQ, например, он не находится в состоянии Runnable
. Независимо от приоритета или привязки, ядро может свободно назначать другие процессы ядру.
Это приводит к тому, что частота выборки оборудования становится более изменчивой и ниже, чем могла бы быть, поскольку ядро нашего ЦП не всегда сразу готово обработать следующее значение SPI
и затем отправить новый запрос выборки.
Вопрос:
Можем ли мы 1) заставить все остальные процессы оставаться вне ядра, чтобы наш процесс мог немедленно реагировать на запросы прерывания, или 2) сохранить наш основной поток в состоянии Runnable, чтобы он всегда был доступен для обработки следующего запроса?