Core (logical/physical) numbers
Количество процессинг-юнитов (физических CPU). Может не совпадать с top (добавляются логические CPU, как в примерах ниже).
$ nproc 4 nproc - print the number of processing units available.
Понятнее всего количество физических и логических ядер посмотреть в выводе lscpu
-
- логические (общее количество на систему) в виде CPU(s). Отображаются все CPU, включая созданные hyperthreading – в данном выводе 2 процессора E5-2620 v3 с 6 физическими ядрами на борту и 12 потокама (12 * 2 = 24).
- физические (количество на сокет) в виде Core(s) per socket
# E5-2620 v3 lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 24 On-line CPU(s) list: 0-23 Thread(s) per core: 2 Core(s) per socket: 6 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 63 Model name: Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz top %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 2.1 us, 2.1 sy, 0.0 ni, 95.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu6 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu8 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu9 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu10 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu11 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu12 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu13 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu14 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu15 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu16 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu17 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu18 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu19 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu20 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu21 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu22 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu23 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
# i3-4360 lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 60 Model name: Intel(R) Core(TM) i3-4360 CPU @ 3.70GHz top %Cpu0 : 0.4 us, 0.0 sy, 0.0 ni, 99.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 0.4 us, 0.4 sy, 0.0 ni, 99.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
isolcpus
- Isolcpus deprecated функционал. У isolcpus есть два существенных недостатка, которых нет у ниже описанного cpuset shield (cset shield):
- для ядер CPU, которые находятся в изоляции не работает scheduler операционной системы и нагрузка одного приложения не будет распределяться по нескольким CPU, даже если так настроен taskset
- isolcpus можно настроить только с перезагрузкой (изменение grub)
Since isolated CPUs are excluded from SMP balancing and the scheduler algorithm, it's not desirable to use them in situations where you want a process balanced across multiple CPUs. In such cases, shielding is more desirable (see the man page for cset-shield): - Normally, when I have isolcpus, starting a process with taskset -c 2-32 means all threads end up on core 2 as isolcpus "removes cores from scheduler" as I was told so there is no load balancing. - Similar to taskset, it's possible to define more than one CPU in a cpuset, however, due to the nature of isolated CPUs, only the first defined CPU will be effective. - Cgroup cpuset is not balancing tasks on CPUs isolated via isolcpus kernel parameter Automated load balancing of a process/task across multiple isolated CPUs is not possible.
Изоляция CPU позволяет “вынести” CPU из общих ресурсов и в последующем прибиндить его к конкретной app, которая потенциально будет работать более стабильно/производительно в такой конфигурации за счет отсутствия переключения контекста и кеша. По факту, пишут, что преимущества изоляции сейчас минимальны и многие приложения прекрасно масштабируются/балансируются на CPU без присвоения им конкретных ядер обработки (запуск нескольких instance приложения без присвоения каждому конкретных ядер).
Since isolated CPUs are excluded from SMP balancing and the scheduler algorithm, it's not desirable to use them in situations where you want a process balanced across multiple CPUs. In such cases, shielding is more desirable (see the man page for cset-shield).
The isolcpus
option can be used to isolate cores from the Linux scheduler. The isolated cores can then be used to dedicatedly run HPC applications or threads. This helps in better application performance due to zero context switching and minimal cache thrashing. It has been verified that core isolation has minimal advantage due to mature Linux scheduler in some circumstances.
Пример настройки – 1) выводим из системы 7 ядер из 8 или 2) с 1 по 19. Нулевое ядро в обоих случаях оставляем системе в GRUB cmdline.
vim.tiny /etc/default/grub GRUB_CMDLINE_LINUX="isolcpus=1,2,3,4,5,6,7" GRUB_CMDLINE_LINUX="isolcpus=1-19" sudo update-grub
You can also use taskset pointed to PID 1. As PID 1 is the standard PID for the first task launched by the kernel, we can take as a pretty good indication that it will reflect whether we have isolcpus working. As in: $taskset -cp 1 pid 1's current affinity list: 0,1 $lscpu | grep CPU.s CPU(s): 4 On-line CPU(s) list: 0-3 NUMA node0 CPU(s): 0-3 As it can be seen, lscpu is showing 4 CPU/cores, while taskset is only showing 0,1, so this shows isolcpus is working here.
Так же можно посмотреть с каким CMDLINE была загружена система.
# cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-3.2.0-4-amd64 root=UUID=fcd249ff-8e89-408d-bc51-e8868dc14748 ro isolcpus=1 quiet
cpuset shield (cset shield)
- (CPUSET/CSET SHIELD, ISOLCPUS, AFFINITY, IxChariot) Конфигурация системы (нагрузчик IxChariot Endpoint) которую я настраивал для создания высокой нагрузки (более 10 gbps TCP трафиком), всего 4 ядра CPU в системе:
- использовал cpuset с shield (cset shield) для ядер CPU 2-3, на которых запускается endpoint процесс с балансировкой нагрузки между ядрами
- использовал isolated CPU для ядра 1 (isolcpus), прерывания очередей нагрузочных интерфейсов (сетевой карты 10G) переведены на отдельное изолированное ядро 1 (smp_affinity) – периодически были всплески на CPU1 до 80%, но редко (для отлова чаще всего нужно использовать top с настройками обновления чаще 1 раз в 3с) в отличии от конфигураций shield 1-3 или default конфигурации
- системные процессы работали на оставшемся ядре 0 – конфиги ниже однозначно проявили себя хуже
- если все держать в общем пуле (linux + endpoint + прерывания) – система (SSH) не тормозит, но производительность упирается в прерывания на нулевом ядре
- если на CPU 0 обрабатывать как прерывания (только на нем), так и системные задачи (linux + прерывания) – система явно упирается в прерывания на нулевом ядре и даже SSH начинает тормозить, результаты ухудшаются
- если выделять два ядра CPU0 + CPU1 под общие задачи прерывания и системные задачи (linux + прерывания), а приложение держать на отдельных двух – все ок и с системой и с результатами тестирования производительности приложения, но потенциально вариант с разделением прерываний на отдельный CPU более стабилен и я остановился на нем
Включает в себя достоинства isolcpus и при этом в этом функционале отсутствуют недостатки isolcpus – одно приложение в группе cset shield балансируется между выделенными в shield ядрами, настройка cset shield возможна без перезагрузок системы.
# INSTALL CPUSET/CSET apt-get install cpuset # CHECK THAT SHIELD OFF taskset -cp 1 pid 1's current affinity list: 0-3 # CREATE SHIELD cset shield --cpu 2-3 --kthread on # RUN APP IN SHIELD cset shield --exec /usr/local/some_application # ALTERNATE set shield --shield --pid 3237 # DELETE APP FROM SHIELD cset shield --unshield --pid 3237 # CHECK taskset -cp 1 # check system pid pid 1's current affinity list: 0-1 taskset -cp 19 # check app pid pid 19's current affinity list: 2-3 cset shield -s # show shield load cset: "user" cpuset of CPUSPEC(2-3) with 13 tasks running cset: done
Если нужно, чтобы cset настраивался сразу при запуске системы – это легко сделать добавив те же команды настройки cset в автостарт системы (напр. /etc/rc.local или systemctl). Единственная особенность – запуск приложения в shield и cset нужно разносить каким-то ожиданием или sleep (на практике достаточно 5 секунд) или проверкой создания, иначе приложение не запустится т.к. cset shield еще не будет создан.
maxcpus
Изменять количество активных CPU в сторону понижения надежнее всего через maxcpus.
I have got some interesting experience with > switching on/off the CPU cores. First, I did the on/off switching of > the i-th CPU core by writing 1/0 values into the > /sys/devices/system/cpu/cpu$i/onlinefile of the working Linux kernel > [2]. Whereas it seemed to work well, when the query rates were > moderate (a few times ten thousand queries per second), it caused > problems in the second case, when I used up to 3 million queries per > second query rates, and thus I rather set the number of active CPU > cores at the DUT by using the maxcpus=nkernel parameter.
interrupts, SMP IRQ affinitY
- Чаще всего для усредненных сетевых application ядро биндится к очереди сетевой карты, прерывания распределяются так же на это ядро (не всегда, даже я делал при ускорении IxChariot отдельные ядра для прерываний) и на это же ядро вешается userspace приложение
- Почему прерывания важны и как их настраивать хорошо описано в статье alibaba cloud и статье Oracle; ниже лишь интересные выдержки
- When the bits for four CPUs are set to f, all CPUs are used to handle interrupts.
CPU ID Binary Hexadecimal CPU 0 0001 1 CPU 1 0010 2 CPU 2 0100 4 CPU 3 1000 8
-
- прерывания – это триггер, сгенерированный девайсом (сетевой картой, дисковым контроллером), получив этот триггер CPU должен его обработать (в том числе остановив текущую задачу)
When a hardware component (such as a disk controller or an Ethernet NIC) needs to interrupt the work of the CPU, it triggers an interrupt. The interrupt notifies the CPU that an event occurred and the CPU should suspend its current work to deal with the event.
-
- во многих случаях несмотря на низкую совокупную утилизацию CPU производительность низка из-за высокой загрузки ядра (или ядер) CPU, обрабатывающего прерывания – к примеру без SMP IRQ affinity все прерывания всех сетевых карт распределены на нулевое ядро CPU0, что, очевидно, может быть bottleneck
In many cases, when overall CPU usage is low but performance is poor, it is usually the CPU core specified to handle interrupts is fully occupied. Let's take NIC interrupts as an example. Without the SMP IRQ affinity, all NIC interrupts are associated with CPU 0. As a result, CPU 0 is overloaded and cannot efficiently process network packets, causing a bottleneck in performance.
-
- распределение прерываний на специальные CPU/группы CPU (лучше группы) в виде SMP IRQ affinity появилось еще в Linux ядре 2.4, к примеру можно переводить полностью NIC на определенные ядра или более стандартно – переводить определенные очереди каждой NIC на отдельные ядра (используя RSS или Soft RSS RPS/RFS). Нежелательно использовать CPU0 для прерываний RPS.
Balancing network interrupts among multiple CPUs increases the performance of network-based operations. In kernel 2.4 and later, Linux improves the capability of assigning specific interrupts to the specified processors (or processor groups). This is called the SMP IRQ affinity, which controls how the system responds to various hardware events. You can limit or redistribute the server workload so that the server can work more efficiently. After you configure the SMP IRQ affinity, multiple NIC interrupts are allocated to multiple CPUs to distribute the CPU workload and speed up data processing. The SMP IRQ affinity requires NICs to support multiple queues. A NIC supporting multiple queues has multiple interrupt numbers, which can be evenly allocated to different CPUs. In the following example, interrupt 27 is allocated to CPU 0 for processing. Generally, you are recommended to leave CPU 0 unused.
-
- ((с другой стороны в Linux по умолчанию работает NAPI)) по идее задачу динамически должен и решает IRQbalance, но по факту
- он часто выключен по умолчанию
- зачастую даже при включении все равно более правильным решением является настройкам вручную прерываний и отключение IRQbalance (лаг на адаптацию при спайках нагрузки, высокий уровень context switch, глюки)
- ((с другой стороны в Linux по умолчанию работает NAPI)) по идее задачу динамически должен и решает IRQbalance, но по факту
Most Linux installations are not configured to balance network interrupts. The default network interrupt behavior uses a single processor (typically CPU0) to handle all network interrupts and can become a serious performance bottleneck with high volumes of network traffic. Balancing network interrupts among multiple CPUs increases the performance of network-based operations. IRQbalance is applicable to most scenarios. However, in scenarios requiring high network performance, you are recommended to bind interrupts manually. IRQbalance can cause some issues during operation: (a) The calculated value is sometimes inappropriate, failing to achieve load balancing among CPUs. (b) When the system is idle and IRQs are in power-save mode, IRQbalance distributes all interrupts to the first CPU, to make other idle CPUs sleep and reduce energy consumption. When the load suddenly rises, performance may be degraded due to the lag in adjustment. (c) The CPU specified to handle interrupts frequently changes, resulting in more context switches. (d) IRQbalance is enabled but does not take effect, that is, does not specify a CPU for handling interrupts.
- IRQbalance помогает в средних сценариях, но по факту:
- Он иногда не работает (у меня так же было) и это приводит к деградации производительности/росту задержек и потерь
- С высокой прозводительностью зачастую лучше настроить прерывания вручную – IRQbalance is applicable to most scenarios. However, in scenarios requiring high network performance, you are recommended to bind interrupts manually.
Настройка affinity позволяет:
-
- привязать процесс к конкретному ядру (конкретным) CPU
- привязать очередь прерываний к конкретному ядру, например, очередь прерываний с сетевой карты биндится к конкретному ядру процессора (напр. так реализовано в TRex)
Часто используется в задачах генерации/обработки большой нагрузки. Привязка приводит к повышению стабильности производительности и росту данной производительности (пример описан в ESXi). Affinity работает зачастую в связке c распределением потоков на базе расчета hash для передаваемых потоков:
-
- на базе сетевой карты RSS, подробнее о очередях RSS сетевых карт в статье про сетевые карты
- на базе софтверного расчета hash/распределения (напр. когда. RSS на сетевой не поддерживается или не реализует необходимое распределение (5-tuple))
Технология RSS позволяет аппаратно раскидывать приходящие на сетевую карту пакеты на несколько процессоров, где они обрабатываются различными потоками. При этом выполнять все операции с пакетом непосредственно на том процессоре, куда пакет аппаратно попал, нецелесообразно, обычно делают так: несколько процессорных ядер выделяется под RSS, где потоки выгребают пакеты из сетевой карты и раскидывают по нескольким очередям, а затем другие потоки-воркеры, работающие на других процессорных ядрах, забирают пакеты из очередей и обрабатывают.
Количество очередей RSS обычно делается равным количеству процессов, на которые трафик распределяется.
Пример моей настройки прерываний на отдельное ядро на практике (работало)
-
Распределение прерываний в smp_affinity появляется сразу после UP интерфейса, независимо от того, есть ли линк или нет. Если интерфейс не в UP – прерывания распределить не получится.
while true; do echo; echo; grep -w "CPU0\|Rescheduling\|eth8\|eth9" /proc/interrupts | sort -n; sleep 1; done CPU0 CPU1 CPU2 CPU3 RES: 84049 43750986 110517787 110615940 Rescheduling interrupts 166: 82474083 0 0 0 IR-PCI-MSI-edge eth8-TxRx-0 167: 24042806 0 0 0 IR-PCI-MSI-edge eth8-TxRx-1 168: 59272802 0 0 0 IR-PCI-MSI-edge eth8-TxRx-2 169: 59361007 0 0 0 IR-PCI-MSI-edge eth8-TxRx-3 170: 4 0 0 0 IR-PCI-MSI-edge eth8 180: 82616626 0 0 0 IR-PCI-MSI-edge eth9-TxRx-0 181: 24207180 0 0 0 IR-PCI-MSI-edge eth9-TxRx-1 182: 59306623 0 0 0 IR-PCI-MSI-edge eth9-TxRx-2 183: 59334616 0 0 0 IR-PCI-MSI-edge eth9-TxRx-3 184: 2 0 0 0 IR-PCI-MSI-edge eth9
echo 000002 > /proc/irq/166/smp_affinity echo 000002 > /proc/irq/167/smp_affinity echo 000002 > /proc/irq/168/smp_affinity echo 000002 > /proc/irq/169/smp_affinity echo 000002 > /proc/irq/170/smp_affinity echo 000002 > /proc/irq/180/smp_affinity echo 000002 > /proc/irq/181/smp_affinity echo 000002 > /proc/irq/182/smp_affinity echo 000002 > /proc/irq/183/smp_affinity echo 000002 > /proc/irq/184/smp_affinity
while true; do echo; echo; grep -w "CPU0\|Rescheduling\|eth8\|eth9" /proc/interrupts | sort -n; sleep 1; done CPU0 CPU1 CPU2 CPU3 RES: 38502 44083017 180343133 172478449 Rescheduling interrupts 166: 83784996 680 0 0 IR-PCI-MSI-edge eth8-TxRx-0 167: 24543343 42381024 0 0 IR-PCI-MSI-edge eth8-TxRx-1 168: 60286755 35225747 0 0 IR-PCI-MSI-edge eth8-TxRx-2 169: 59985599 34032738 0 0 IR-PCI-MSI-edge eth8-TxRx-3 170: 2 0 0 0 IR-PCI-MSI-edge eth8 180: 83957687 682 0 0 IR-PCI-MSI-edge eth9-TxRx-0 181: 24894775 42820948 0 0 IR-PCI-MSI-edge eth9-TxRx-1 182: 60905927 35291571 0 0 IR-PCI-MSI-edge eth9-TxRx-2 183: 59187673 34322303 0 0 IR-PCI-MSI-edge eth9-TxRx-3 184: 4 0 0 0 IR-PCI-MSI-edge eth9
Настройка распределения прерываний на все ядра.
echo 00000f > /proc/irq/65/smp_affinity # eth0-tx-0 echo 00000f > /proc/irq/66/smp_affinity # eth0-tx-1 echo 00000f > /proc/irq/67/smp_affinity # eth0-tx-2 echo 00000f > /proc/irq/68/smp_affinity # eth0-tx-3 echo 00000f > /proc/irq/69/smp_affinity # eth0-rx-0 echo 00000f > /proc/irq/70/smp_affinity # eth0-rx-1 echo 00000f > /proc/irq/71/smp_affinity # eth0-rx-2 echo 00000f > /proc/irq/72/smp_affinity # eth0-rx-3
Посмотреть привязку процесса к CPU
Посмотреть привязку PID к CPUI можно множеством способов. Первый способ с taskset считаю самый простой и надежный, пользовался им при работе с isolcpus, cset shield (выше).
# С помощью самого taskset ~$ taskset -p 6099 pid 6099's current affinity mask: 3 # С помощью ps (столбец PSR) sh-4.4# ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm | grep softirq PID TID CLS RTPRIO NI PRI PSR %CPU STAT WCHAN COMMAND 9 9 TS - 0 19 0 5.7 S - ksoftirqd/0 16 16 TS - 0 19 1 0.0 S - ksoftirqd/1 21 21 TS - 0 19 2 0.0 S - ksoftirqd/2 26 26 TS - 0 19 3 0.0 S - ksoftirqd/3 31 31 TS - 0 19 4 0.0 S - ksoftirqd/4 36 36 TS - 0 19 5 0.0 S - ksoftirqd/5 41 41 TS - 0 19 6 0.0 S - ksoftirqd/6 46 46 TS - 0 19 7 0.0 S - ksoftirqd/7 # С помощью top (столбец P) > Hit f to get into the Fields Management window > Select P (Last Used Cpu) ((выбирается backspace)) > Esc scroll coordinates: y = 1/195 (tasks), x = 1/13 (fields) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND P 713 root 20 0 36760 27652 3656 S 0,0 0,3 165:04.34 collectl 1 335 root 20 0 60180 24396 7080 S 0,0 0,3 10:56.09 systemd-journal 0 1 root 20 0 107272 10412 7732 S 0,0 0,1 16:26.84 systemd 0 18601 www-data 20 0 1934252 10156 2472 S 0,0 0,1 0:00.00 apache2 1 # Можно даже сделать простой скрипт, который рассчитает количество процессов на ядро - в примере наиболее загруженны по количеству процессов ядра 0 и 1 root@us:~# ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm | awk '{print $7}' | sort | uniq -c | sort -n 1 PSR 7 10 7 11 7 3 7 4 7 5 7 7 7 8 7 9 8 2 9 6 55 1 73 0
Taskset
Привязать PID к CPU удобнее всего с помощью taskset. Так же можно использовать cset/cpuset без shield (с shield описано выше).
# Можно напрямую указать конкретный CPU (affinity), range или list (man taskset --cpu-list 0-2,6) taskset --cpu-list 1 /root/redkin/tcpreplay-master/src/tcpreplay -i enp3s0f1 --topspeed --loop=1000000000000 --duration=600 --preload-pcap /root/redkin/test.pcap & taskset --cpu-list 2 /root/redkin/tcpreplay-master/src/tcpreplay -i enp3s0f1 --topspeed --loop=1000000000000 --duration=600 --preload-pcap /root/redkin/test.pcap & # Можно оперировать coremask, но это чаще всего менее удобно taskset 0xFFFFFFFF /root/redkin/tcpreplay-master/src/tcpreplay -i enp3s0f1 --topspeed --loop=1000000000000 --duration=600 --preload-pcap /root/redkin/test.pcap & # HEX ~$ taskset -p 0x00000001 6099 pid 6099's current affinity mask: 3 pid 6099's new affinity mask: 1 ~$ taskset -p 0x00000002 6099 pid 6099's current affinity mask: 1 pid 6099's new affinity mask: 2 # DECIMAL >sudo taskset -pc 7 17551 pid 17551's current affinity list: 7 pid 17551's new affinity list: 7
Могут быть проблемы с привязкой для kernel threads, по идее они решаются только персборкой ядра с отключением флага PF_NO_SETAFFINITY для kernel процессов, но не факт (не изучил до конца этот вопрос – сомнения на основе статьи).
>ps -p 828 PID TTY TIME CMD 828 ? 00:00:00 nfsiod >sudo taskset -pc 7 828 pid 828's current affinity list: 0-11 taskset: failed to set pid 828's affinity: Invalid argument Many kernel threads set the flag PF_NO_SETAFFINITY: To change the affinity, you would have to change the kernel. https://stackoverflow.com/questions/25359565/how-one-can-set-affinity-for-kernel-threads https://stackoverflow.com/questions/60100719/check-value-of-pf-no-setaffinity
Пример привязки на сетевом оборудовании
Прерывание на сетевой карте привязываем к ядру CPU. Из /proc/interrupts можно извлечь распределение прерываний по очередям.
Помещает очередь прерываний первого интерфейса (по умолчанию 60, если в качестве интерфейса захвата eth1) на ЦПУ 0. cat 1 > /proc/irq/60/smp_affinity Если задействован второй интерфейс необходимо определить его очередь прерываний. Для этого выполнить команду: grep <наименование интерфейса> /proc/interrupts В полученном списке необходимо найти очередь для RX. Для установки свободного процессора необходимо использовать следующую формулу: 2 в степени номер свободного процессора в шеснадцатиричной форме. Например 8 свободный процессор (2^7) = 128. В шестнадцатиричной форме равно 80. cat 80 > /proc/irq/69/smp_affinity
Number cores: 8 pgrep <proc> | xargs -I PID_PROC taskset -p PID_PROC pid 23116's current affinity mask: 2 pid 23117's current affinity mask: 4 pid 23118's current affinity mask: 8 pid 23119's current affinity mask: 10 pid 23120's current affinity mask: 20 pid 23121's current affinity mask: 40 pid 23122's current affinity mask: 80 pid 23123's current affinity mask: 100 /interfaces |tr ',' ' > '| xargs -I ETH grep ETH /proc/interrupts | cut -d: -f1 | xargs -I IRQ_NUMBER head -v /proc/irq/IRQ_NUMBER/smp_affinity ==> /proc/irq/133/smp_affinity <== 0002 ==> /proc/irq/134/smp_affinity <== 0004 ==> /proc/irq/135/smp_affinity <== 0008 ==> /proc/irq/136/smp_affinity <== 0010 ==> /proc/irq/137/smp_affinity <== 0020 ==> /proc/irq/138/smp_affinity <== ...
CheckPoint рекомендует IRQ между сетевыми картами рекомендует делать такими, чтобы они не пересекались (IRQ swizzling). Рекомендуют отключать Hyper-Threading.
https://downloads.checkpoint.com/fileserver/SOURCE/direct/ID/7555/FILE/Performance_tests_methodology.pdf Hardware Configuration for Open Server Interfaces that are constantly used should not share the same IRQ. To prevent the use of the same IRQ in such a situation perform the following: 1. Upgrade BIOS to enable IRQ swizzling (for platforms that support this option). IRQ swizzling is designed to enable PCI-E based NICs to have different IRQ pools. For example, two PCI-E dual cards are put in two separate busses, they will both receive the same IRQs (16 & 17 for example). Upgrading the BIOS to include support for IRQ swizzling will enable the second NIC to have different IRQs (18, 19 for example). 2. Select the ports that do not share the same IRQ for the heavily used network interfaces. For example, configure the internal/external/sync subnets so that they will not share IRQ interfaces. 3. Use gigabit based equipment (NICs, switches, cables) 4. Disable hyper-threading