专栏首页北京马哥教育Linux 多核下绑定硬件中断到不同 CPU

Linux 多核下绑定硬件中断到不同 CPU

硬件中断发生频繁,是件很消耗 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 上的,很显然 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

为了不让 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、这个问题不太好回答,要记住的是性能优化是一个过程而不是结果,不是看了些文档改了改参数就叫优化了,后面还需要大量的测试、监测以及持续的观察和改进。

本文分享自微信公众号 - 马哥Linux运维(magedu-Linux)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux Shell 流程控制语句实例

    linux shell 有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个...

    小小科
  • 【Linux调优】linux系统性能监控与优化(1)–简介

    最近几年做了很多性能优化的事情,但是一直没有形成一套理论,也没有很好的形成一个好的排查问题的流程,每次做优化,大多是经验式的查找,最近看了一下这本书《linux...

    小小科
  • 「技能分享」有效处理空值的10个技巧,学不会算我输

    当我们开始使用Java进行编程时,很多人会把null值当做敌人,并且害怕NullPointerExceptions,下面给大家分享10个有效处理空值的技巧。

    小小科
  • MySQL binlog日志大小超过限定范围

    my.cnf中有两个参数设置: expire_logs_days = 7 #binlog保留时间7天 max_binlog_size = 1G ...

    MySQL轻松学
  • 我的产品安全观

    我的安全产品观 这是一篇杂想,也是一篇回忆,算是给我“伪产品经理”经历的一次总结。 同其他互联网产品一样,一个完整的安全产品团队至少会包括产品经理/技术/运营/...

    企鹅号小编
  • Android基础知识:项目架构基础概述

    前段时间由于工作需要,学习了关于组件化和插件化架构相关的知识。查阅了很多Android开发架构的资料,组件化自己写了个简单的Demo并且开始了原有项目的改造,插...

    Android技术干货分享
  • Layui-admin-iframe通过页面链接直接在iframe内打开一个新的页面,实现单页面的效果

      使用Layui-admin做后台管理框架有很长的一段时间了,但是一直没有对框架内iframe菜单栏切换跳转做深入的了解。今天有一个这样的需求就是通过获取超链...

    追逐时光
  • 基于Golang&MongoDB快速构建RESTful服务

    近年来,“微服务”在软件架构出现频次越来越高,其思想主要是指将一个大型的单个应用服务拆分为多个微服务,每个微服务在其自己的进程中运行,并采用轻量级的协议进程通信...

    JimmyDeng
  • 为什么寄存器比内存快?

    计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘。

    Linux阅码场
  • 为什么寄存器比内存快?

    计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘。 ? 同样都是晶体管存储设备,为什么寄存器比内...

    ruanyf

扫码关注云+社区

领取腾讯云代金券