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  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457514.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457514.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457514.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

請列舉你了解的分布式鎖_這幾種常見的“分布式鎖”寫法,搞懂再也不怕面試官,安排!...

什么是分布式鎖&#xff1f;大家好&#xff0c;我是jack xu&#xff0c;今天跟大家聊一聊分布式鎖。首先說下什么是分布式鎖&#xff0c;當我們在進行下訂單減庫存&#xff0c;搶票&#xff0c;選課&#xff0c;搶紅包這些業務場景時&#xff0c;如果在此處沒有鎖的控制&#x…

leetcode 268

等差數列求值 1 class Solution {2 public:3 int missingNumber(vector<int>& nums) {4 int nnums.size();5 int kn*(n1)/2;6 for(int i0;i<n;i)7 k-nums[i];8 return k;9 } 10 }; 轉載于:https://www.cnblogs.…

301緩存重定向?301 Moved Permanently (from disk cache)

今天在寫一個博客系統時&#xff0c;發現首頁數據經常刷新不出來&#xff0c;甚至后端根本就沒有接受到這個請求&#xff0c;以為是Ajax的問題&#xff0c;但通過抓包發現Ajax請求確實已經發出去了&#xff0c;但狀態碼是 301 Moved Permanently (from disk cache),301是永久重…

Firefox 50優化Electrolysis

Mozilla正式發布Firefox 50。最新的版本中提升了來自多個內容進程用戶的用戶體驗&#xff0c;并修復了十幾個高影響的安全漏洞。\\在Firefox最新版本的變更中&#xff0c;我們注意到了它對于Electrolysis的進一步改進。Electrolysis是Mozilla實現在后臺進程中呈現和執行web相關…

ModuleNotFoundError: No module named '_ctypes' ERROR:Command errored out with exit status 1: python

Ubuntu下載 nginx 時報錯&#xff1a; ERROR: Command errored out with exit status 1:command: /usr/local/bin/python3.7 -c import sys, setuptools, tokenize; sys.argv[0] ""/tmp/pip-install-7e0xdb36/uwsgi/setup.py""; __file__""/tmp…

python opc plc_PYthon簡易OPC數據采集寫入Access

利用hollias comm opcserver 與Python實現交互。代碼如下&#xff1a;# -*- coding: utf-8 -*-from sys import *from getopt import *#from os import * 造成f open(test.txt, r) TypeError: an integer is required錯誤import signalimport sysimport osimport typesimport …

邊工作邊刷題:70天一遍leetcode: day 73

Read N Characters Given Read4 I/II 要點&#xff1a;這題的要點就是搞清楚幾個變量的內在邏輯&#xff1a;只有buffer是整4 bytes的。而client要讀的bytes&#xff08;需求&#xff09;和實際上disk上有的bytes&#xff08;供給&#xff09;都是不整的。所以&#xff0c; 循環…

javascript時間戳和日期字符串相互轉換

1 <html xmlns"http://www.w3.org/1999/xhtml">2 <head>3 <meta http-equiv"Content-Type" content"text/html; charsetutf-8" />4 <script type"text/javascript">5 // 獲取當前時間戳(以s為單位)6 var time…

wireshark 十六進制過濾_CTF流量分析之wireshark使用

01.基本介紹在CTF比賽中&#xff0c;對于流量包的分析取證是一種十分重要的題型。通常這類題目都是會提供一個包含流量數據的pcap文件&#xff0c;參賽選手通過該文件篩選和過濾其中無關的流量信息&#xff0c;根據關鍵流量信息找出flag或者相關線索。pcap流量包的分析通常都是…

vim 插件管理

1  進入自己的vim mkdir ./bundle/vundle 2  在vimrc同級中執行 git clone https://github.com/gmarik/vundle.git ./bundle/vundle 將一些插件文件 下載到./bundle/vundle中 3  編寫自己的vim配置&#xff0c;其實很簡單 set nocompatible " be iMp…

ubuntu install wiznote

sudo add-apt-repository ppa:wiznote-team #添加官方源sudo apt-get update #更新源sudo apt-get install wiznote #安裝為知筆記

python 對象序列化 pickling_python操作文件——序列化pickling和JSON

當我們在內存中定義一個dict的時候&#xff0c;我們是可以隨時修改變量的內容的&#xff1a;>>> ddict(namewc,age28)>>>d{name: wc, age: 28}我們可以隨時修改name和age的值。但是當我們重新運行程序的時候&#xff0c;name、age的初始化值還是wc和28&#…

python實現Redis訂閱發布

Redis 發布訂閱 Redis 發布訂閱可以用在像消息通知&#xff0c;群聊&#xff0c;定向推送&#xff0c;參數刷新加載等業務場景 發布訂閱模型有三個角色&#xff1a; 發布者&#xff08;Publisher&#xff09;訂閱者(Subscriber)頻道(channel) 每個訂閱者可以訂閱多個頻道&am…

nfs的快速部署

1、nfs內核自帶協議模塊不用安裝&#xff0c;如果沒有yum安裝yum -y install nfs-utils2、配置vim /etc/exports #配置文件 此文件一般為空&#xff0c;編寫格式為&#xff1a; /share/word 192.168.31.254(rw) 192.168.31.252(ro) # 共享/share/word目錄給192.168.…

redistemplate怎么修改數據_如何使用RedisTemplate訪問Redis數據結構?

在springboot項目中&#xff0c;集成各種框架變得非常容易。下面簡單介紹一下如何在springboot項目中集成單機模式redis。集群模式也差不多&#xff0c;這里就不過多介紹了。首先你得安裝redis服務&#xff0c;無論在linux還是windows系統上。如果沒有安裝&#xff0c;請自行百…

HyperLogLog原理與在Redis中的使用

Redis-HyperLogLog 基于HyperLogLog算法&#xff0c;使用極小的空間完成巨量運算 Redis 中HyperLogLog 基本使用 常用命令 PFADD key element [element …]: 將任意數量的元素添加到指定的 HyperLogLog 里面。PFCOUNT key [key …]: 計算hyperloglog的獨立總數prmerge destk…

iOS開發UI篇—xib的簡單使用

一、簡單介紹 xib和storyboard的比較&#xff0c;一個輕量級一個重量級。 共同點&#xff1a; 都用來描述軟件界面 都用Interface Builder工具來編輯 不同點: Xib是輕量級的&#xff0c;用來描述局部的UI界面 Storyboard是重量級的&#xff0c;用來描述整個軟件的多個界面&…

【云棲計算之旅】線下沙龍第2期精彩預告:Docker在云平臺上的最佳實踐

Docker是一個開源的應用容器引擎&#xff0c;提供了一種在安全、可重復的環境中自動部署軟件的方式&#xff0c;允許開發者將他們的應用和依賴包打包到一個可移植的容器中&#xff0c;然后發布到任何流行的Linux機器上&#xff0c;也可以實現虛擬化。容器完全使用沙箱機制&…

小程序mpvue圖片繪制水印_開發筆記:使用 mpvue 開發斗圖小程序

之前用過 wepy 框架寫了個小程序 GitHub - yshkk/shanbay-mina: 基于 wepy 框架的 “扇貝閱讀” 微信小程序 &#xff0c;感覺寫法上類似 vue&#xff0c;但不那么徹底。現在美團點評發布的 mpvue 支持開發者可以用 vue 的語法開發微信小程序&#xff0c;正好有強需求需要一個斗…

mysql int類型的長度值

整數類型的存儲和范圍(來自mysql手冊) 類型字節最小值最大值(帶符號的/無符號的)(帶符號的/無符號的)TINYINT1-1281270255SMALLINT2-3276832767065535MEDIUMINT3-83886088388607016777215INT4-2147483648214748364704294967295BIGINT8-92233720368547758089223372036854775807…