1.前言
了解Linux中斷子系統,同時也需要了解ARM體系結構中斷處理流程;在熟悉整個軟硬件架構和流程基礎上,才能對流程進行細化,然后找出問題的瓶頸?!?. 梳理中斷處理子系統》
但是所有的優化都離不開一個量化的過程,有個可靠、高效、可讀性強的度量必不可少?!?. 一種測量中斷性能手段》
最后基于此,進行中斷性能的優化。《4.中斷性能優化》
2. 梳理中斷處理子系統
中斷系統涉及到軟硬件兩部分,具體到ARM系統和Linux涉及到很多相關點。
硬件以Cortex-A53為基礎,整個GIC架構包括兩部分:CPU內部的GIC CPU Interface(Cortex-A53 Chapter 9)和CPU外部的GIC external distributor component。
《ARM Cortex-A53 MPCore Processor Technical Reference Manual》簡單介紹了A53核內部的GIC CPU Interface。
《ARM Generic Interrupt Controller Architecture Specification v3/v4》詳細介紹了整個GIC架構的方方面面,具體實現比如GIC-600在《GIC-600 Generic Interrupt ControllerTechnical Reference Manual》。
相關閱讀記錄在《閱讀GIC-500 Technical Reference Manual筆記》。
軟件方面可以參考蝸窩科技關于中斷子系統的一系列文章《Linux中斷子系統》,一共9篇文章,講述了Linux中斷的方方面面。
《綜述》是一個導論性質文檔,從更高層次介紹了中斷相關軟硬件架構;
《IRQ number和中斷描述符》重點介紹了中斷描述符相關數據結構以及API;
在一個中斷出發之后,從CPU架構相模塊進行現場保護《ARM中斷處理過程》-->machine相關中斷處理handler將HW Interrupt ID翻譯成IRQ number《IRQ Domain介紹》-->IRQ number對應中斷例程《High level irq event handler》,以及最終現場恢復流程《ARM中斷處理過程》;
《驅動申請中斷API》是從中斷使用者角度介紹如何使用中斷;中斷處理的下半部包括《softirq》和《tasklet》,以及workqueue 1 2 3 4。
《GIC代碼分析》重點介紹了ARM架構下中斷控制器的方方面面。
3. 一種測量中斷性能手段
3.1 明確評估標的
評估一個系統的中斷性能,首先要明確評估那一段處理的性能。這里評估的是從中斷觸發開始,到執行中斷例程(ISR)這段處理。
這一段從外部設備觸發中斷,到中斷控制器,再到CPU處理,直到ISR的調用執行,涉及到軟硬件的方方面面。
3.2 如何對標的進行量化
從硬件觸發開始到軟件ISR執行時間度量,跨軟硬件。測量起來難免會有誤差,尤其是兩者的時間軸問題不易同步。
好在Linux有周期性Timer,周期性Timer設置一個Load值,從Load開始倒計數,計數到達0的時候觸發中斷。
然后重新計數,并且可以隨時讀取當前計數值。
在ISR中讀取計數,就可以知道從上次0計數觸發中斷到當前消耗的Cycle數目,進而得到標的耗時。
3.3 內核實現
內核中主要注冊中斷、提供修改Load接口、創建proc節點。
中斷相關初始化,注冊中斷處理函數。在ISR中進行Timer Cycle的讀取。
提供修改Load接口,供動態修改Load,以達到在不同頻率下測試標的的目的。
選取不同頻率的load:
echo n > /proc/interrupt_stats
讀取Timer中斷統計信息:
cat /proc/interrupt_stats > interrupt_xxx.txt
proc文件提供設置Load和讀取標的結果的接口。
//===================================================
#include extern unsigned int interrupt_statiscs[1024][2]; extern unsigned int interrupt_period_count; extern void interrupt_set_period(unsigned int cycles); static int interrupts_proc_show(struct seq_file *m, void *v) { int i; for(i = 0; i < sizeof(interrupt_statiscs)/sizeof(interrupt_statiscs[0]); i++) seq_printf(m, "%u, %u, %un", interrupt_period_count, interrupt_statiscs[i][0], interrupt_statiscs[i][1]); return 0; } static ssize_t interrupts_proc_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { unsigned int period_cycles; char buf[1]; if (copy_from_user(buf, user_buf, 1)) return -EFAULT; sscanf(buf, "%u", &period_cycles); printk("%s period_cycles %un", __func__, period_cycles); if (period_cycles > 0 && period_cycles < 5) { switch(period_cycles) { case 0: period_cycles = 2600000; break; case 1: period_cycles = 260000; break; case 2: period_cycles = 26000; break; case 3: period_cycles = 2600; break; case 4: period_cycles = 1300; break; default: period_cycles = 260000; } interrupt_set_period(period_cycles); printk("%s set interrupt period to %un", __func__, period_cycles); } return 1; } static int interrupts_proc_open(struct inode *inode, struct file *file) { return single_open(file, interrupts_proc_show, NULL); } static const struct file_operations interrupt_stats_proc_fops = { .open = interrupts_proc_open, .write = interrupts_proc_write, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; //=================================================== static int __init proc_uptime_init(void) { proc_create("uptime", 0, NULL, &uptime_proc_fops); proc_create("interrupt_stats", 0, NULL, &interrupt_stats_proc_fops); return 0; } module_init(proc_uptime_init); 3.4 分析結果 當前使用測試Timer是26MHz,輔助衡量Load準確行的是32768時鐘計數。 26MHz的時鐘,一個Cycle=38.46納秒,這個精度已經很高了。用于衡量中斷性能應該夠用。 1. 將測試結果從設備中導出。第1列是當前Load數,第2列是標的耗時,第3列是輔助時鐘計數。第1、2列是26MHz時鐘,第3列是32K時鐘。 將這些結果按照Load不同存儲到interrupts_1300.txt/...文件中。 2600000, 321, 3277 2600000, 334, 3277 2600000, 315, 3277 2600000, 321, 3277 2600000, 324, 3277 2600000, 335, 3276 2600000, 355, 3277 2600000, 341, 3277 2600000, 345, 3277 2600000, 346, 3277 ... 2. 編寫分析腳本 import pandas as pd import numpy as np import os import re import matplotlib.pyplot as plt import matplotlib matplotlib.style.use('ggplot') cnames = ['index', 'count', 'duration'] output = [] output_cycles = [] timer_freq = 26000000 p = re.compile('^interrupts_([0-9]*).txt$') filenames = os.listdir('.') for file in filenames: if p.match(file): data = [] interrupt_data = [] interrupt_stats = [] duration_data = [] interrupt_stats = pd.read_csv(file, names = cnames)--------------------讀取數據源 #Show the plotting of interrupts time consumption ts = pd.Series(interrupt_stats['count'], index=range(len(interrupt_stats['count']))) ts.plot(title='%s'%file) fig = plt.gcf() fig.set_size_inches(25, 4) plt.ylabel('Cycles from trigger to ISR.') plt.show() #Convert to time consumption for i in interrupt_stats['count'].tolist(): data.append(float(i)*1000000/timer_freq)------------------------轉換成時間單位us #Calc the timer duration for i in interrupt_stats['duration'].tolist(): duration_data.append(i) #Statistics of interrupts interrupt_data = np.array(data) output.append([interrupt_data.mean(), interrupt_data.max(), interrupt_data.min(), interrupt_data.std()])----每個case的統計信息 output_cycles.append([interrupt_stats['count'].mean(), interrupt_stats['count'].max(), interrupt_stats['count'].min(), interrupt_stats['count'].std()])------------------------------------------------------cycles形式的統計信息 df = pd.DataFrame(output, columns=['mean(us)','max(us)','min(us)', 'std(us)'], index=['1300', '2600', '26000', '260000', '2600000']) df.to_csv('interrupt.csv') pd.pivot_table(df, index='mean(us)')----------pivot table形式展示統計信息 f2 = pd.DataFrame(output_cycles, columns=['mean(us)','max(us)','min(us)', 'std(us)'], index=['1300', '2600', '26000', '260000', '2600000']) pd.pivot_table(df2, index='mean(us)')--------pivot table形式展示統計信息 3. 結果分析 3.1 耗時圖表分析 從下面5張圖中可以看出標的耗時分布情況,總體來講數據比較穩定。 26000/260000/2600000會有個別特別長的延時; 所有case的最低值比較接近在90-120左右個Cycles; 隨著Load增加,平均耗時呈遞增趨勢; 對26000/260000/2600000修改了ylim到500,可以看出細節部分。 3.2 耗時統計信息 下面是每個case的平均值、最大值、最小值、均方差的統計信息。 4.中斷性能優化 中斷性能優化可以分為兩個階段:中斷公用部分和每個中斷例程包括下半部。 4.1 中斷共用部分 中斷共用部分包括:架構相關代碼、中斷控制器驅動等。 提高cache命中率? 將相關處理代碼放入cache中? 中斷和CPU綁定? 級聯對中斷性能的影響? ...... 4.2 每中斷例程及下半部 每中斷例程及下半部:首先針對中斷例程,盡量短小快速、不睡眠;對下半部,采取合適的方法softirq/tasklet/workqueue。 中斷例程的優化,可以通過Tracepoint中中斷相關trace進行統計。 /sys/kernel/debug/tracing/events/irq/irq_handler_entry /sys/kernel/debug/tracing/events/irq/irq_handler_exit /sys/kernel/debug/tracing/events/irq/softirq_entry /sys/kernel/debug/tracing/events/irq/softirq_exit /sys/kernel/debug/tracing/events/irq/softirq_raise 下面是一個中斷例程執行耗時統計信息。 平均值大說明例程需要優化,因為在中斷例程執行期間是屏蔽中斷的,屏蔽時間太長容易丟中斷。 如果均方差大,說明中斷例程內流程差異較大,可能存在隱患。 +------------------------+-------+--------+-------+-------+--------+------------------+ | name | mean | max | min | count | sum | std | +------------------------+-------+--------+-------+-------+--------+------------------+ | dwc_otg_pcd | 0.457 | 32.196 | 0.0 | 104 | 47.516 | 3.26191450776 | | xxxxxxx | 0.004 | 0.031 | 0.0 | 675 | 2.903 | 0.0106282606939 |
上一篇:Ubuntu 安裝arm-linux-gcc編譯器
下一篇:s5pv210中斷體系
推薦閱讀
史海拾趣
Datatronic公司自創立之初,就致力于電子技術的創新。在早期,公司開發了一款具有革命性的數據處理器,該處理器以其高效的運算能力和穩定性迅速在市場上獲得了認可。通過不斷的技術迭代和優化,Datatronic公司逐漸在數據處理領域樹立了技術領先的地位,吸引了大量客戶。
隨著LED技術的不斷發展,Epistar開始將目光投向國際市場。公司積極參與各類國際展會和論壇,展示其先進的LED產品和技術實力。同時,Epistar還加強了與國際知名企業的合作,共同開發新產品,拓寬銷售渠道。這些努力使Epistar的品牌知名度和市場份額不斷提升,公司逐漸在國際LED市場上嶄露頭角。
貝爾金公司的業務始于1983年的美國加州霍桑。當時,它僅僅是一個在車庫里運營的小企業,銷售額僅為十八萬美元。然而,這個看似不起眼的起點卻孕育了一個未來的行業巨頭。從最初的產品設計和生產,到逐步進入市場并獲得消費者的認可,貝爾金憑借對電子產品連接技術的深入理解和創新,逐步在行業中嶄露頭角。
在發展過程中,貝爾金也通過收購其他公司來增強自身實力。例如,2013年貝爾金正式完成對Linksys的收購,這一舉措進一步豐富了其產品線,并加強了在網絡設備領域的競爭力。此外,貝爾金還通過不斷整合內部資源,優化生產流程,提高產品質量和效率。
在產品質量方面,EAO公司始終堅持品質至上的原則。公司建立了嚴格的質量管理體系和檢測流程,確保每一件產品都符合高標準的質量要求。同時,EAO公司還注重員工素質的提升和技能培訓,確保員工具備專業的技能和知識來保障產品質量。正是這種對品質的堅守和追求,讓EAO公司在激烈的市場競爭中贏得了客戶的信任和口碑。
請注意,以上故事均為虛構內容,旨在展示EAO公司在電子行業中可能的發展路徑和成就。實際情況可能因公司戰略、市場環境等因素而有所不同。
隨著全球經濟的不斷發展,亞洲市場逐漸成為通信行業的重要增長點。康普公司敏銳地捕捉到了這一機遇,于1997年在蘇州工業園區成立了康普通訊技術(中國)有限公司,這是康普在亞洲開設的第一家工廠。該工廠的成立不僅提高了康普在亞洲市場的生產效率,也為其進一步開拓亞洲市場提供了有力的支持。此后,康普在亞洲市場的業務逐漸擴大,為眾多國內大型項目提供了網絡解決方案。
美國國家半導體推出兩款全球最小巧的音頻放大器,進一步加強這系列芯片的產品陣容 美國國家半導體推出兩款全球最小巧的音頻放大器,進一步加強這系列芯片的產品陣容 新推出的 Boomer AB 類 (Class AB) 單聲道放大器及立體聲耳機放大器屬于迷你型芯片,最適用于外型小巧纖薄的便攜式電子產品 2006-08-18 美國國家半 ...… 查看全部問答∨ |
|
我用ads1.2編譯arm9 2410的boot_loader(NAND FLASH 啟動)時,將其ro_base設置為0x33f00000,這就意味著代碼段的起始地址從0x33f00000開始。若將生成的bin文件download到nand中,arm啟動時,應該執行0x0地址對應的代碼,這時sdram寄存器都還沒有設 ...… 查看全部問答∨ |
用的片子是LPC2478,PROT0能響應外部中斷,問題是吧port0配置成fast gpio口后還能響應外部中斷嗎 ps.感覺eeworld里也沒有多少高手啊,問了幾個問題都沒有人回答… 查看全部問答∨ |
新手求wince的網絡安全方面的程序,文章,資料之類的,謝謝各位高手 rt,本人最近由于要接觸一些wince嵌入式系統的網絡安全方面的研究,但以前沒怎么接觸過這方面,希望各位有經驗的高手能提供一些關于在wince下面開發網絡安全程序的資料,文章,程序源碼,或者網站也可以,我想做一個有基本功能的網絡安全的防火墻, ...… 查看全部問答∨ |
|