Я разработал сервер потокового видео в golang, который принимает несколько потоков через обычное TCP-соединение и транслирует их по HTTP.
Это работает на моем кластере raspberryPi, который я использую в Docker Swarm. Сервер горизонтально распределен между всеми малинами. Все экземпляры получают все потоки, распределение нагрузки происходит при распределении между многими клиентами по HTTP.
Один поток довольно тяжелый, около 16 Мбит / с используемой полосы пропускания.
Это работает довольно хорошо, так как я получаю 32 кадра в секунду почти без задержки.
Я решил проверить, сколько процессора и памяти мои программы используют через htop. Когда я запускаю его как пользователь root, я вижу, что мой сервер использует около 50% ЦП, что, по моему мнению, было нормально, так как он принимал 4 одновременных потока со скоростью 32 кадра в секунду. Но затем я запустил htop с пользователем pi и заметил, что другой процесс ksoftirqd
потребляет еще 50% ЦП (не знаю, почему я не вижу процесс при запуске htop от имени root).
Я провел некоторое исследование и узнал, что это особый небольшой процесс, который обрабатывает отложенные системные прерывания (или что-то подобное). Это имеет смысл, поскольку я получаю большую нагрузку через интерфейс eth0.
Затем я посмотрел в /proc/interrupts
:
CPU0 CPU1 CPU2 CPU3
16: 0 0 0 0 bcm2836-timer 0 Edge arch_timer
17: 92241367 299499641 352012196 317363321 bcm2836-timer 1 Edge arch_timer
23: 288978 0 0 0 ARMCTRL-level 1 Edge 3f00b880.mailbox
24: 25146874 0 0 0 ARMCTRL-level 2 Edge VCHIQ doorbell
46: 0 0 0 0 ARMCTRL-level 48 Edge bcm2708_fb dma
48: 0 0 0 0 ARMCTRL-level 50 Edge DMA IRQ
50: 0 0 0 0 ARMCTRL-level 52 Edge DMA IRQ
51: 530982 0 0 0 ARMCTRL-level 53 Edge DMA IRQ
54: 13573 0 0 0 ARMCTRL-level 56 Edge DMA IRQ
55: 0 0 0 0 ARMCTRL-level 57 Edge DMA IRQ
56: 0 0 0 0 ARMCTRL-level 58 Edge DMA IRQ
59: 3354 0 0 0 ARMCTRL-level 61 Edge bcm2835-auxirq
62: 3696376760 0 0 0 ARMCTRL-level 64 Edge dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
79: 0 0 0 0 ARMCTRL-level 81 Edge 3f200000.gpio:bank0
80: 0 0 0 0 ARMCTRL-level 82 Edge 3f200000.gpio:bank1
83: 0 0 0 0 ARMCTRL-level 85 Edge 3f804000.i2c
84: 0 0 0 0 ARMCTRL-level 86 Edge 3f204000.spi
86: 460008 0 0 0 ARMCTRL-level 88 Edge mmc0
87: 5270 0 0 0 ARMCTRL-level 89 Edge uart-pl011
92: 4975621 0 0 0 ARMCTRL-level 94 Edge mmc1
220: 3352 0 0 0 bcm2835-auxirq 0 Edge serial
FIQ: usb_fiq
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 41355699 278691553 311249136 291769396 Rescheduling interrupts
IPI3: 7758 9176 8710 9334 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 1387927 1201820 2860486 1356720 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
Как вы можете видеть, прерывание 62 - это то, которое вызывается чаще всего и обрабатывается только CPU0. Я подозреваю, что это прерывание является прерыванием eth0 (как я могу это подтвердить?). Поэтому я подумал, что могу настроить это так, чтобы прерывание обрабатывалось всеми процессорами.
Итак, я посмотрел на /proc/irq/62/smp_affinity_list
, и его содержимое равно 0-3
, которое кажется правильным, а содержимое файла /proc/irq/62/smp_affinity
равно f
, которое также кажется правильным.
Так что я не понимаю, почему прерывание 62 обрабатывается только CPU0.
Также не понимаю, почему я могу видеть ksoftirqd
в htop, только если я запускаю его как pi вместо root (владелец процесса - root).
Как я могу настроить Raspberry для обработки этого прерывания на всех процессорах?
* РЕДАКТИРОВАТЬ *
Я проверял это только на одной из малины, принадлежащей скоплению. Проверяя это на других хостах, я увидел похожие результаты (только чуть более низкое использование процессора). Как ни странно, на другой малине нет ksoftirqd
процесса, потребляющего столько ресурсов ЦП.