Category: Tech articles

  • SMP-affinity

    Не многие знают, что они могут значительно повысить производительность сетевой подсистемы Linux на мультипроцессорных или многоядерных системах за счёт распределения системных прерываний от сетевых адаптеров на различные процессоры/ядра.

    Дело в том, что при интенсивной сетевой нагрузке сетевые платы вызывают слишком много системных прерываний (Вы можете посмотреть нагрузку на процессоры Вашего сервера создаваемую обработкой системных прерываний с помощью утилиты top – параметр si), что влечёт за собой потерю пакетов проходящих на/через сетевые интерфейсы.

    Допустим, что у Вас в системе есть два процессора и два сетевых адаптера, сделаем так, чтобы системные прерывания от eth0 обрабатывались первым процессором, а прерывания от второго сетевого адаптера eth1 обрабатывались вторым процессором.

    Проверим как обрабатываются прерывания от сетевых адаптеров в данный момент: cat /proc/interrupts

               CPU0       CPU1
      0: 1025359421 1011223877    IO-APIC-edge  timer
      1:          7     443237    IO-APIC-edge  i8042
      6:          3          2    IO-APIC-edge  floppy
      7:          0          0    IO-APIC-edge  parport0
      8:          0   18718112    IO-APIC-edge  rtc
      9:          1          0    IO-APIC-level  acpi
     12:   11950434        756    IO-APIC-edge  i8042
    90:      790345          0    IO-APIC-level  eth0
    169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
    177:          79073095  0     IO-APIC-level  eth1
    209:          0          0    IO-APIC-level  uhci_hcd:usb4
    217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
    225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
    NMI:          0          0
    LOC: 2036559271 2036559270
    ERR:          0
    MIS:          0

    как мы можем видеть в приведённом примере первый сетевого адаптер «висит» на IRQ 90, а второй на IRQ 177. Причём явно видно что прерывания как от первого, так и второго сетевого адаптера обрабатываются первым процессором в системе.

    Исправим данную ситуацию, для этого нам необходимо записать число “2″ в файл /proc/irq/177/smp_affinity

    echo \"2\" >/proc/irq/177/smp_affinity

    после этого посмотрим как изменилась ситуация:

    cat /proc/interrupts
               CPU0       CPU1
      0: 1025359421 1011223877    IO-APIC-edge  timer
      1:          7     443237    IO-APIC-edge  i8042
      6:          3          2    IO-APIC-edge  floppy
      7:          0          0    IO-APIC-edge  parport0
      8:          0   18718112    IO-APIC-edge  rtc
      9:          1          0    IO-APIC-level  acpi
     12:   11950434        756    IO-APIC-edge  i8042
    90:      790345          0    IO-APIC-level  eth0
    169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
    177:   79073095    3672362    IO-APIC-level  eth1
    209:          0          0    IO-APIC-level  uhci_hcd:usb4
    217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
    225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
    NMI:          0          0
    LOC: 2036559271 2036559270
    ERR:          0
    MIS:          0

    как видим счётчик прерываний для eth1 на CPU0 не изменился, но появились цифры ниже CPU1 т.е. обработка прерываний от второго сетевого адаптера eth1 обрабатывается вторым процессором в системе.

    Небольшое объяснение насчёт того, что же значит цифра 2 !
    Linux каждому cpu в системе ставит в соответствие некую цифру обозначающую данный процессор в системе. Ниже приведена таблица для 4-х процессорной системы

                двоичный    шестнадцатеричный
        CPU 0    0001         1
        CPU 1    0010         2
        CPU 2    0100         4
        CPU 3    1000         8

    т.е. если бы у нас в вышеприведённом примере было не 2 а четыре процессора и мы бы хотели обрабатывать прерывания от eth1 на третьем процессоре CPU2, то нам для этого пришлось бы вместо 2 записать цифру 4 в файл /proc/irq/177/smp_affinity .

    Любознательный читатель может спросить, что же было бы если бы мы записали в данный файл число которого нет в приведённой таблице, например echo “3″ >/proc/irq/177/smp_affinity. Ответ прост прерывания от eth1 обрабатывались бы первым и вторым процессором т.к.

               двоичный     шестнадцатеричный
        CPU 0    0001         1
      + CPU 2    0010         2
        -----------------------
                 0011         3

    Стоит особо отметить, нет смысла обрабатывать системные прерывания от одного сетевого адаптера на нескольких процессорах/ядрах т.к. суммарно system interrupts от данного адаптера никогда не превысит 100%, т.е. максимум, что Вы сможете получить это 50% загрузки на одном процессоре/ядре и 50% на другом.

    Дополнение: у компании Intel существуют чипсеты 82575 и 82576 сетевые карты на базе которых имеют несколько очередей каждая из которых может обрабатываться отдельным ядром/процессором.

    Выглядит это следующим образом

    cat /proc/interrupts
               CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
      0:   72718527   72693470   72701000   72694778   72698856   72705975   72697612   72709066    IO-APIC-edge  timer
      1:          0          1          0          0          0          0          1          0    IO-APIC-edge  i8042
      6:          0          0          2          0          0          0          1          0    IO-APIC-edge  floppy
      8:          0          0          0          0          0          1          0          0    IO-APIC-edge  rtc
      9:          0          0          0          0          0          0          0          1   IO-APIC-level  acpi
     14:     143672     144923     144966     146156     144955     144426     144156     144955    IO-APIC-edge  ata_piix
     15:     892735     915776     908202     913235     910358     903767     912399     900143    IO-APIC-edge  ide1
     58:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb3
     66:         64          0          0 2259148530          0          0          0          0       PCI-MSI-X  eth0-tx0
     74: 2992330737          0          0          0          0          0          0          0       PCI-MSI-X  eth0-rx0
     82:       4197 3028991669          0          0          0          0          0          0       PCI-MSI-X  eth0-rx1
     90:       4091          0 3008220806          0          0          0          0          0       PCI-MSI-X  eth0-rx2
     98:       4092          0          0 2999334745          0          0          0          0       PCI-MSI-X  eth0-rx3
    106:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth0
    114:          7          0          0          0          0          0          0 2265679966       PCI-MSI-X  eth1-tx0
    122:          1          0          0          0 3906833163          0          0          0       PCI-MSI-X  eth1-rx0
    130:          1          0          0          0          0 3957703625          0          0       PCI-MSI-X  eth1-rx1
    138:          1          0          0          0          0          0 3918250115          0       PCI-MSI-X  eth1-rx2
    146:          1          0          0          0          0          0          0 3928688764       PCI-MSI-X  eth1-rx3
    154:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth1
    169:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb5
    177:          1          0          0          0          1          1          1          1   IO-APIC-level  uhci_hcd:usb4, aic94xx
    185:          0          0          0          0          0          0          0          0   IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
    NMI:          0          0          0          0          0          0          0          0
    LOC:  581643579  581643516  581643609  581643411  581643494  581643475  581643531  581643008
    ERR:          0
    MIS:          0
    

    За данную информацию спасибо Marian Ivasiuk

    Подробнее прочитать о SMP-Affinity можно по этому адресу http://www.cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt
    http://centos.alt.ru/?p=26