Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)

转载 - Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)

作者

digoal

日期

2016-11-20

标签

Linux , IRQ , 中断 , CPU亲和 , 绑定中断处理CPU


背景

原文

http://www.vpsee.com/2010/07/load-balancing-with-irq-smp-affinity/

原文

硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。现在的服务器上动不动就是多 CPU 多核、多网卡、多硬盘,如果能让网卡中断独占1个 CPU (core)、磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担、提高整体处理效率。VPSee 前天收到一位网友的邮件提到了 SMP IRQ Affinity,引发了今天的话题:D,以下操作在 SUN FIre X2100 M2 服务器+ 64位版本 CentOS 5.5 + Linux 2.6.18-194.3.1.el5 上执行。

什么是中断

中文教材上对 “中断” 的定义太生硬了,简单的说就是,每个硬件设备(如:硬盘、网卡等)都需要和 CPU 有某种形式的通信以便 CPU 及时知道发生了什么事情,这样 CPU 可能就会放下手中的事情去处理应急事件,硬件设备主动打扰 CPU 的现象就可称为硬件中断,就像你正在工作的时候受到 QQ 干扰一样,一次 QQ 摇头就可以被称为中断。

中断是一种比较好的 CPU 和硬件沟通的方式,还有一种方式叫做轮询(polling),就是让 CPU 定时对硬件状态进行查询然后做相应处理,就好像你每隔5分钟去检查一下 QQ 看看有没有人找你一样,这种方式是不是很浪费你(CPU)的时间?所以中断是硬件主动的方式,比轮询(CPU 主动)更有效一些。

好了,这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?不同设备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?这个很容易,不是每个 QQ 号码都不相同吗?同样的,系统上的每个硬件设备都会被分配一个 IRQ 号,通过这个唯一的 IRQ 号就能区别张三和李四了。

在计算机里,中断是一种电信号,由硬件产生,并直接送到中断控制器(如 8259A)上,然后再由中断控制器向 CPU 发送信号,CPU 检测到该信号后,就中断当前的工作转而去处理中断。然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。现在来看一下中断控制器,常见的中断控制器有两种:可编程中断控制器 8259A 和高级可编程中断控制器(APIC),中断控制器应该在大学的硬件接口和计算机体系结构的相关课程中都学过。传统的 8259A 只适合单 CPU 的情况,现在都是多 CPU 多核的 SMP 体系,所以为了充分利用 SMP 体系结构、把中断传递给系统上的每个 CPU 以便更好实现并行和提高性能,Intel 引入了高级可编程中断控制器(APIC)。

光有高级可编程中断控制器的硬件支持还不够,Linux 内核还必须能利用到这些硬件特质,所以只有 kernel 2.4 以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为 SMP IRQ Affinity. 更多介绍请参看 Linux 内核源代码自带的文档:linux-2.6.31.8/Documentation/IRQ-affinity.txt

如何绑定中断处理CPU

先看看系统上的中断是怎么分配在 CPU 上的,很显然 CPU0 上处理的中断多一些:

# cat /proc/interrupts
           CPU0       CPU1
  0:  918926335          0    IO-APIC-edge  timer
  1:          2          0    IO-APIC-edge  i8042
  8:          0          0    IO-APIC-edge  rtc
  9:          0          0   IO-APIC-level  acpi
 12:          4          0    IO-APIC-edge  i8042
 14:    8248017          0    IO-APIC-edge  ide0
 50:        194          0   IO-APIC-level  ohci_hcd:usb2
 58:      31673          0   IO-APIC-level  sata_nv
 90:    1070374          0         PCI-MSI  eth0
233:         10          0   IO-APIC-level  ehci_hcd:usb1
NMI:       5077       2032
LOC:  918809969  918809894
ERR:          0
MIS:          0

即能看到中断号,也能看到每个CPU的中断处理次数。

为了不让 CPU0 很累怎么把部分中断转移到 CPU1 上呢?或者说如何把 eth0 网卡的中断转到 CPU1 上呢?先查看一下 IRQ 90 中断的 smp affinity,看看当前中断是怎么分配在不同 CPU 上的(ffffffff 意味着分配在所有可用 CPU 上):

# cat /proc/irq/90/smp_affinity
7fffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff

在进一步动手之前我们需要先停掉 IRQ 自动调节的服务进程,这样才能手动绑定 IRQ 到不同 CPU,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。如果想修改 IRQ 90 的中断处理,绑定到第2个 CPU(CPU1):

# /etc/init.d/irqbalance stop  

# echo "2" > /proc/irq/90/smp_affinity

(上面的 echo “2” 是怎么来的?为什么是 ”2“?请参考本文末尾:计算 SMP IRQ Affinity)过段时间在看 /proc/interrupts,是不是 90:eth0 在 CPU1 上的中断增加了(145)、在 CPU0 上的中断没变?不断打印 /proc/interrupts 就会发现 eth0 在 CPU0 上的中断数始终保持不变,而在 CPU1 上的中断数是持续增加的,这正是我们想要的结果:

# cat /proc/interrupts
           CPU0       CPU1
  0:  922506515          0    IO-APIC-edge  timer
  1:          2          0    IO-APIC-edge  i8042
  8:          0          0    IO-APIC-edge  rtc
  9:          0          0   IO-APIC-level  acpi
 12:          4          0    IO-APIC-edge  i8042
 14:    8280147          0    IO-APIC-edge  ide0
 50:        194          0   IO-APIC-level  ohci_hcd:usb2
 58:      31907          0   IO-APIC-level  sata_nv
 90:    1073399        145         PCI-MSI  eth0
233:         10          0   IO-APIC-level  ehci_hcd:usb1
NMI:       5093       2043
LOC:  922389696  922389621
ERR:          0
MIS:          0

有什么用

在网络非常 heavy 的情况下,对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力;对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。

VPSee 经常收到网友来信问到如何优化 Linux、优化 VPS、这个问题不太好回答,要记住的是性能优化是一个过程而不是结果,不是看了些文档改了改参数就叫优化了,后面还需要大量的测试、监测以及持续的观察和改进。

其他

把irqbalance 停掉會不會有其他問題出玩?

不会有什么严重问题,但是没有 irqbalance 也没有合理的做手动 irq 绑定的话会有性能问题。手动 irq 只推荐给很 heavy、很特殊的情况,比如带多网卡多硬盘的网络存储服务器,一般机器一般应用还是用 irqbalance 省心。

事实上以前 Linux 是不推荐使用 irqbalance 的,原因在于当时的 irqbalance 实现很简单,没有什么优化作用,后来的 irqbalance (cache topology + power aware) 有了很大改进,在多核上表现良好。

计算 SMP IRQ Affinity

“echo 2 > /proc/irq/90/smp_affinity” 中的 ”2“ 是怎么来的,这其实是个二进制数字,代表 00000010,00000001 代表 CPU0 的话,00000010 就代表 CPU1, “echo 2 > /proc/irq/90/smp_affinity” 的意思就是说把 90 中断绑定到 00000010(CPU1)上。所以各个 CPU 用二进制和十六进制表示就是:

               Binary       Hex
    CPU 0    00000001         1
    CPU 1    00000010         2
    CPU 2    00000100         4
    CPU 3    00001000         8

如果我想把 IRQ 绑定到 CPU2 上就是 00000100=4:

# echo "4" > /proc/irq/90/smp_affinity

如果我想把 IRQ 同时平衡到 CPU0 和 CPU2 上就是 00000001+00000100=00000101=5

# echo "5" > /proc/irq/90/smp_affinity

需要注意的是,在手动绑定 IRQ 到 CPU 之前需要先停掉 irqbalance 这个服务,irqbalance 是个服务进程、是用来自动绑定和平衡 IRQ 的:

# /etc/init.d/irqbalance stop

还有一个限制就是,IO-APIC 有两种工作模式:

logic 和 physical,

在 logic 模式下 IO-APIC 可以同时分布同一种 IO 中断到8颗 CPU (core) 上(受到 bitmask 寄存器的限制,因为 bitmask 只有8位长。);

在 physical 模式下不能同时分布同一中断到不同 CPU 上,比如,不能让 eth0 中断同时由 CPU0 和 CPU1 处理,这个时候只能定位 eth0 到 CPU0、eth1 到 CPU1,也就是说 eth0 中断不能像 logic 模式那样可以同时由多个 CPU 处理。

下面给大家提供一个计算小脚本值提供中断在单CPU上

#!/bin/bash
#Author Jiaion MSN:Jiaion@msn.com
[ $# -ne 1 ] && echo ‘$1 is Cpu core number’ && exit 1  

CCN=$1
echo “Print eth0 affinity”
for((i=0; i<${CCN}; i++))
do
echo ==============================
echo "Cpu Core $i is affinity"
((affinity=(1<<i)))
echo "obase=16;${affinity}" | bc
echo ==============================
done  
时间: 2024-11-02 09:56:23

Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)的相关文章

Linux 系统下查看硬件信息命令大全

Linux 系统下查看硬件信息命令大全 有许多命令可以用来查看 Linux 系统上的硬件信息.有些命令只能够打印出像 CPU 和内存这一特定的硬件组件信息,另外一些命令可以查看多种硬件组件的信息. 这个教程可以带大家快速了解一下查看各种硬件设备的信息和配置详情的最常用的命令. lscpu lscpu命令能够查看 CPU 和处理单元的信息.该命令没有任何其他选项或者别的功能. lscpu 运行该命令会看到下面输出: lspci lspci是另一个命令行工具,可以用来列出所有的 PCI 总线,还有与

Linux下的硬件安装

1.安装 Linux 要占用多少硬盘空间? 决定于要安装什么distribution的Linux,以及需要装入多少应用程序,是否安装原代码等. 例如最基本的Slackware Linux大约需要10MB的空间,包括X Windows则要80M,假如要把基本系统工具程序.常用应用软件以及TCP/IP网络软件安装的话 ( 即A.B.N系列编号软件),差不多40-50MB,如要全部安装,大约200MB左右. 至于RedHat Linux,最小化安装(仅仅最基本的系统)大约需要60M,缺省安装大约要25

Linux系统下多网卡绑定操作方法

在Linux系统中,通常会将多个网卡绑定为一个逻辑网卡,这样可以提高网络的稳定性,那么要如何将多个网络绑定为一个呢?下面小编就给大家介绍下Linux下多网卡绑定的bond模式原理. 将多个Linux网络端口绑定为一个,可以提升网络的性能,比如对于备份服务器,需要在一个晚上备份几个T的数据,如果使用单个的千兆网口将会是很严 重的瓶颈.其它的应用,比如ftp服务器,高负载的下载网站, 都有类似的问题.因此使用Linux teaming或bond来绑定多个网卡作为一个逻辑网口,配置单个的IP地址,会大

Linux环境下进程中断的原因

问题描述 Linux环境下进程中断的原因 linux环境下,哪些原因可能造成某进程中断?或者说,代码中哪些不合理的地方可能会引起进程的中断? 解决方案 内存溢出等,程序无法处理的异常都会造成程序进程中断 解决方案二: 中断是一种是一种机制: 看下面的一段汇编代码: .section .data string:.ascii "hello" .section .text .globl _start _start: movl $4,%eax#sys_call_num movl $2,%ebx

Linux系统下Apache服务器设置与优化

Apache服务器的设置文件位于/usr/local/apache/conf/目录下,传统上使用三个配置文件httpd.conf,access.conf和srm.conf,来配置Apache服务器的行为. httpd.conf提供了最基本的服务器配置,是对守护程序httpd如何运行的技术描述:srm.conf是服务器的资源映射文件,告诉服务器各种文件的MIME类型,以及如何支持这些文件:access.conf用于配置服务器的访问权限,控制不同用户和计算机的访问限制:这三个配置文件控制着服务器的各

【Linux】Linux双网卡绑定实现

Linux双网卡绑定实现就是使用两块网卡虚拟成为一块网卡,这个聚合起来的设备看起来是一个单独的以太网接口设备,通俗点讲就是两块网卡具有相同的IP地址而并行链接聚合成一个逻辑链路工作.    在正常情况下,网卡只接收目的硬件地址(MAC Address)是自身Mac的以太网帧,对于别的数据帧都滤掉,以减轻驱动程序的负担.但是网卡也支持另外一种被称为混杂promisc的模式,可以接收网络上所有的帧,比如说tcpdump,就是运行在这个模式下.bonding也运行在这个模式下,而且修改了驱动程序中的m

阿里云使用Linux进行域名绑定和服务器登录有哪些问题

域名绑定 Tomcat服务绑定域名的方法 ECS Linux系统域名绑定host后ping测试不生效 Nginx绑定多个域名的方法 ECS Linux无法解析hosts里面绑定域名的排查方法 服务器登陆 ECS Linux无法远程连接的检查方法 ECS Linux远程ssh报错read: Connection reset by peer ECS Linux ssh连接服务器报错CONNECTION RESET by peer ECS Linux通过Xshell 配置密钥key免密码登录 ECS服

Linux/Unix下ODBC的安装、配置与编程

odbc|unix|编程 Linux/Unix下ODBC的安装.配置与编程 齐亮 (cavendish@eyou.com) 2002 年 7 月 本文主要内容是介绍ODBC的简单原理,以及如何在Linux/Unix下进行ODBC的安装.配置与编程. 一. ODBC原理 ODBC 是Open Database Connect 即开放数据库互连的简称,它是由Microsoft 公司于1991 年提出的一个用于访问数据库的统一界面标准,是应用程序和数据库系统之间的中间件.它通过使用相应应用平台上和所需

Windows及Linux平台下的计时函数总结

本文对Windows及Linux平台下常用的计时函数进行总结,包括精度为秒.毫秒.微秒三种精度的各种函数. 比如Window平台下特有的Windows API函数GetTickCount().timeGetTime().及QueryPerformanceCounter(), Linux平台下特有的gettimeofday()函数,以及标准的C/C++函数time()和clock().下面分别对此进行简单介绍并附上示例代码. 通用的C/C++计时函数time()和clock() time_t ti