我的目标是配置我们的 CentOS(“免费” RHEL)5.x 服务器以运行自定义低延迟网络程序。我想尝试将以太网 NIC 中断处理绑定到运行该程序的同一 CPU(希望提高缓存利用率)。此过程的第一步是确定 NIC 的 IRQ。
下面是一台服务器上 /proc/interrupts 的内容(请注意,为了简洁起见,我删除了 CPU 2 到 14):
CPU0 CPU1 CPU15
0: 600299726 0 0 IO-APIC-edge timer
1: 3 0 0 IO-APIC-edge i8042
8: 1 0 0 IO-APIC-edge rtc
9: 0 0 0 IO-APIC-level acpi
12: 4 0 0 IO-APIC-edge i8042
50: 0 0 0 IO-APIC-level uhci_hcd:usb6, uhci_hcd:usb8
58: 6644 25103 0 IO-APIC-level ioc0
66: 0 0 0 IO-APIC-level ata_piix
74: 221 533830 0 IO-APIC-level ata_piix
98: 35 0 2902361 PCI-MSI-X eth1-0
106: 61 11 3841 PCI-MSI-X eth1-1
114: 28 0 61452 PCI-MSI-X eth1-2
122: 24 1586 22 PCI-MSI-X eth1-3
130: 2912 0 337 PCI-MSI-X eth1-4
138: 21 0 28 PCI-MSI-X eth1-5
146: 21 0 56 PCI-MSI-X eth1-6
154: 34 1 1 PCI-MSI-X eth1-7
209: 23 0 0 IO-APIC-level ehci_hcd:usb1
217: 0 0 0 IO-APIC-level ehci_hcd:usb2, uhci_hcd:usb5, uhci_hcd:usb7
225: 0 0 0 IO-APIC-level uhci_hcd:usb3
233: 0 0 0 IO-APIC-level uhci_hcd:usb4
NMI: 7615 2989 2931
LOC: 600328144 600328099 600327086
ERR: 0
MIS: 0
为什么“eth1-X”形式的“eth1”有多个条目?
另外,“/sys/class/net/eth1/device/irq”的内容是“90”。但是上面的中断列表中没有90。
假设我只看“eth1-0”,即 IRQ 98。/proc/irq/98/smp_affinity 的内容是:
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00008000
这是一个数字列表,而不仅仅是一个数字。
那么我该如何设置 eth1 的 smp_affinity?
我找到的所有在线示例和文档均未提及任何此类情况;它们在 /proc/interrupts 中始终只有一个“ethX”条目;指示的中断与 /sys/class/net/ethX/device/irq 匹配;并且 /proc/irq/N/smp_affinity 中只有一个数字。
顺便说一下,这个应用程序极其延迟敏感。我们禁用 C 状态和处理器频率调整(因为这些功能会导致过多延迟)。 微在这里,分秒必争。
编辑:我偶然发现了以下网页 http://www.kernel.org/doc/man-pages/online/pages/man7/cpuset.7.html 虽然它是关于 cpuset 的,但它有一个标题为“掩码格式”的部分,我认为与我在 /proc/irq//smp_affinity 文件中看到的一样。引用:
此格式以十六进制显示每个 32 位字(使用 ASCII 字符“0”-“9”和“a”-“f”);如果需要,字会用前导零填充。对于长度超过一个字的掩码,字之间使用逗号分隔符。字按大端顺序显示,即最高有效位在前。字内的十六进制数字也按大端顺序显示。
根据位掩码的大小,显示的 32 位字的数量是显示位掩码所有位所需的最小数量。
掩码格式的示例:
00000001 # just bit 0 set 40000000,00000000,00000000 # just bit 94 set 00000001,00000000,00000000 # just bit 64 set 000000ff,00000000 # bits 32-39 set 00000000,000E3862 # 1,5,6,11-13,17-19 set
设置位 0、1、2、4、8、16、32 和 64 的掩码显示为:
00000001,00000001,00010117
第一个“1”代表位 64,第二个“1”代表位 32,第三个“1”代表位 16,第四个“1”代表位 8,第五个“1”代表位 4,“7”代表位 2、1 和 0。
答案1
为什么“eth1-X”形式的“eth1”有多个条目?
因为有多个 tx/rx 队列。这些队列通常是 (本地地址、端口、远程地址、端口) 和其他内容的哈希值。假设您的流量源很少,那么抑制多个队列可能会使您的应用程序更具确定性。或者,如果这样更容易,您可以查找算法并避免使用临时端口。
答案2
您是否在使用实时内核?您是否在利用cgroups
或cpusets
隔离您的应用程序?如果您使用的是普通发行版内核,那么您将错过大量延迟增益。此外,我看到 16 个 CPU 核心。这表明已启用超线程。您如何知道您绑定的是真实核心还是逻辑核心?
答案3
检查是否有目录/sys/class/net/eth1/device/msi_irqs/
。如果有,请忽略内容/sys/class/net/eth1/device/irq
。此网络设备有多个 rx/tx 队列,因此有多个 IRQ。这些 IRQ 对应于目录中文件的名称/sys/class/net/eth1/device/msi_irqs/
。