
來自 Industrial-Control SIG的郭皓
将在 openEuler Developer Day 2022 分享
《openEuler在嵌入式和實時性方面的思考與實踐》
歡迎大家觀看直播
openEuler 22.03 LTS 版本新增了 Preempt_RT 核心實時更新檔,提供軟實時特性。該特性由 Industrial-Control SIG 引入,并得到 Kernel SIG、Embedded SIG 和 Yocto SIG 配合與支援,已經被內建到openEuler 22.03 LTS Server 和 openEuler 22.03 LTS Embedded 中。
什麼是實時系統
實時系統的典型定義如下:“所謂實時系統,就是系統中計算結果的正确性不僅取決于計算邏輯的正确性,還取決于産生結果的時間。如果完成時間不符合要求,則可以認為系統發生了問題。”也就是說,不管實時應用程式執行的是何種任務,它不僅需要正确執行該任務而且必須及時完成。目前,Preempt_RT 維護者 Thomas Gleixner 給出的“實時”含義是:它和指定的一樣快。
Linux 作為一種通用作業系統,随着時間的推移,在功能和時序行為方面一直在發展,以便适合許多其他更具挑戰性的場景;尤其是實時系統對 Linux 的實時性改造一直從未停止過。
對 Linux 進行實時性改造,通常可從兩個大的方向來着手。一個方向是從 Linux 核心内部開始,直接修改其核心源代碼,其典型代表是 Preempt_RT 實時更新檔;另一個方向則是從 Linux 核心的外圍開始,實作一個與 Linux 核心共存的實時核心,即采用雙核心方法,其典型實作為 RTAI/Linux,即現在的 Xenomai。
因為 Xenomai 實時核心與 Linux 核心共存,Xenomai 實時核心小而精巧,能夠很好地控制其中的代碼品質。Xenomai 實時核心完成了基本的硬體抽象層、任務排程管理和程序間通信管理子產品等,能夠滿足一些硬實時系統的需求。然而,其上的實時應用通常分為實時和非實時兩部分來完成 ,實時部分必須使用 Xenomai 提供的特有的 API;非實時部分則可以使用 Linux 提供的系統調用。與 Preempt_RT 實時程式設計相比,Xenomai 程式設計實作更為困難,軟體移植難度更大。
與雙核心機制方案相比,Preempt_RT 實時更新檔最大的優勢在于它遵循 POSIX 标準,使用該更新檔的實時系統應用程式和驅動程式與非實時系統的應用和驅動程式差異很小。是以,在使用該更新檔的平台上做相應的開發比雙核心機制的方案更容易。另外,該更新檔與硬體平台相關性小,可移植性高。由于 Linux 核心過于龐大,有着較多關中斷、關搶占代碼,加上複雜的記憶體管理、排程器代碼邏輯等衆多不确定性因素,使得 Preempt_RT 雖然具有較好的軟實時性,但在硬實時性方面有所欠缺。
什麼是 Preempt_RT
Preempt_RT 更新檔開發始于 2005 年。之後由德國 OSADL 組織贊助,Ingo Molnar、Thomas Gleixner 和 Steven Rostedt 三人共同發起,旨在将 Linux 核心的最大線程切換延遲從無限制的毫秒數降低到數十微秒的有界值。2016 年以後成為 Linux 基金會下屬合作項目。目前 Preempt_RT 的贊助者來自 ARM、BMW、CIP、ELISA、Intel、National Instruments、OSADL、RedHat 和 Texas Instruments 等。經過 Preempt_RT 和 Linux 核心工程師在搶占、實時性方面的努力,Linux 核心的搶占延遲降低了幾個數量級,使其能夠與商業實時作業系統競争。業界知名的 MontaVista Linux、WindRiver Linux、TimeSys Linux 都有 RT 更新檔的身影。像 RTJVM、RTKVM、RTDocker、RTAndroid 等曾經出現過的 Preempt_RT 衍生用例,響應速度都有着不同程度的提升。
多年來,該更新檔的許多部分已被納入主線 Linux,包括高分辨率計時器(2.6.16)、優先級繼承(2.6.18)、可搶占的 RCU(2.6.25)、核心互斥量和線程中斷處理程式(2.6.30)、完全 Tickless 機制(3.10)、DL 排程器(EDF 排程算法)(3.14)、實時搶占鎖(5.15)。然而,該更新檔的核心部分仍然在主線之外。從近幾年的 Preempt_RT 更新檔來看,目前的主要工作不是開發新功能,而是專注于增量式引入主線和特定架構的支援。
目前 openEuler 22.03 LTS 主線核心版本為 Linux Kernel 5.10,有 180 把鎖無法搶占,其中 8 把鎖在 RT 更新檔中強制修改成無法搶占。在最新的 5.17 核心中,Preempt_RT 更新檔大小為 265KB,有 189 把鎖仍然無法搶占,RT 更新檔不再強制修改鎖為無法搶占。
目前 Preempt_RT 主要特性
- 臨界區可搶占
- 中斷處理程式可搶占
- 關中斷代碼序列可搶占
- 帶有優先級繼承機制的核心自旋鎖和信号量
- 線程化處理 RCU
- 降低延遲措施
部署方法
二進制部署
二進制部署可以安裝 openEuler 22.03 LTS 官方源中 rpm 包,需要 root 權限,指令如下:
# yum install kernel-rt
完成安裝後重新開機裝置,在 GRUB 引導界面選擇 Preempt_RT 核心
openEuler (5.10.0-60.18.0.rt62.52.oe2203.aarch64) 22.03 LTS
即可。啟動後檢視核心,即完成 openEuler 22.03 LTS Preempt_RT 二進制部署。
# uname -r
5.10.0-60.18.0.rt62.52.oe2203.aarch64
擷取源碼
openEuler 22.03 LTS
kernel-rt
源碼可以直接從官方源擷取,查詢指令如下:
# yum search kernel-rt
...
kernel-rt.src : Linux Kernel
若源裡包含
kernel-rt
源碼,則可使用如下方式下載下傳并安裝:
# yumdownloader --source kernel-rt.src
# rpm -ivh kernel-rt-5.10.0-60.18.0.rt62.52.oe2203.src.rpm && cd ~/rpmbuild
源碼目錄樹如下:
# tree
.
├── SOURCES
│ ├── cpupower.config
│ ├── cpupower.service
│ ├── extra_certificates
│ ├── kernel.tar.gz
│ ├── mkgrub-menu-aarch64.sh
│ ├── patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch
│ ├── patch-5.10.0-60.10.0-rt62.patch
│ ├── pubring.gpg
│ ├── sign-modules
│ └── x509.genkey
└── SPECS
└── kernel-rt.spec
表1:kernel-rt源碼包主要檔案
檔案 | 說明 |
kernel.tar.gz | 核心源碼 |
patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch | openeuler_defconfig 檔案更新檔 |
patch-5.10.0-60.10.0-rt62.patch | Preempt_RT 更新檔 |
kernel-rt.spec | Preempt_RT 核心 spec 檔案 |
源碼部署
源碼擷取後,複制以下檔案到自定義目錄:
# ll
total 186M
-rw-r--r--. 1 root root 185M Apr 2 14:27 kernel.tar.gz
-rw-r--r--. 1 root root 4.5K Apr 2 14:27 patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch
-rw-r--r--. 1 root root 773K Apr 2 14:27 patch-5.10.0-60.10.0-rt62.patch
更新檔合入步驟如下:
# tar -xzf kernel.tar.gz && cd kernel
# patch -p1 < ../patch-5.10.0-60.10.0-rt62.patch
# patch -p1 < ../patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch
源碼編譯安裝:
# make openeuler_defconfig && make -j`nproc`
# make modules_install && make install
# grub2-mkconfig -o $GRUB_CONFIG_PATH
嵌入式系統部署方法
嵌入式部署 Preempt_RT 方法參見:
https://openeuler.gitee.io/yocto-meta-openeuler/features/preempt_rt.html
實時性能測試
表2:縮略語
縮略語 | 英文全名 | 說明 |
RT 核心 | Realtime kernel | 實時核心,本文指 openEuler 22.03 LTS 釋出的 核心 |
非 RT 核心 | / | 非實時核心,實時核心,本文指 openEuler 22.03 LTS 釋出的 核心 |
測試環境
表3:測試軟體環境
版本名稱 | 來源 |
openEuler 22.03 LTS 核心 | openEuler 22.03 LTS 官方源 |
openEuler 22.03 LTS 核心 | openEuler 22.03 LTS 官方源 |
表4:測試硬體環境
硬體型号 | 硬體配置資訊 | 備注 |
飛騰 D2000 | CPU:8 核 記憶體:8GB 儲存設備:SSD | 桌上型電腦 |
樹莓派 4B | CPU:Cortex-A72 * 4 記憶體:8GB 儲存設備:SanDisk Ultra 16GB micro SD | 開發闆 |
飛騰 2000 | CPU:4 核 記憶體:16GB 儲存設備:SSD | 桌上型電腦 |
表5:測試軟體
測試軟體 | 功能 | 軟體版本 |
rt-test(cyclictest) | 通過 cyclictest 工具,每項測試 1000 萬次,輸出平均延遲(Avg)和最大延遲(MAX) | 1.00 |
stress | 壓力測試工具,用于模拟測試 CPU 負載,記憶體負載,IO 負載等 | 1.0.4 |
iperf3 | 網絡測試工具,用于模拟測試網絡負載 | 3.6 |
memtester | 記憶體測試工具,用于模拟測試記憶體負載 | 4.5.1 |
shell 腳本 | 用于輪詢測試,測試資訊的收集整理 | — |
測試結果
基于上述硬體測試環境,在 CPU 隔離、空負載、CPU 負載、記憶體負載、IO 負載和網卡負載等不同條件下的測試資料:
表6:詳細測試結果(機關微秒)
「歸納如下:」
- 通過表 6 資料可以判斷,在五種負載情況下并且 CPU 不隔離,RT 核心比非 RT 核心實時性要強。非 RT 核心與 RT 核心在 CPU 不隔離情況下,五種負載對應峰值的比值如表 7(比值資料越大表明非 RT 核心實時性越差):
表7:非RT核心與RT的核心峰值延遲比值資料表
平台 | 空負載 | CPU 負載 | 記憶體負載 | IO 負載 | 網卡負載 |
飛騰 D2000 | 22.7 | 117.1 | 51.0 | 184.6 | 2.9 |
樹莓派 4B | 3.6 | 2.9 | 4.3 | 0.8 | 1.5 |
飛騰 2000 | 5.4 | 4.3 | 5.3 | 34.7 | 10.6 |
「以上資料表明,RT 核心的峰值延遲普遍要優于非 RT 核心。」
- 結合四種裝置的峰值延遲來看,CPU 負載對實時性影響一般小于 IO 和記憶體負載,而網卡負載影響最小。四種裝置在兩種核心下,CPU、記憶體、IO 和網卡負載與空負載比值如表 8(比值越小越穩定):
表8:負載與空負載峰值延遲比值表
平台 | CPU 負載 | 記憶體負載 | IO 負載 | 網卡負載 |
飛騰 D2000(非 RT 核心) | 5.2 | 43.1 | 212.8 | 2.7 |
樹莓派 4B(非 RT 核心) | 0.8 | 2.7 | 1.0 | 0.7 |
飛騰 2000(非 RT 核心) | 0.8 | 18 | 26.8 | 1.9 |
飛騰 D2000(RT 核心) | 1.0 | 19.2 | 26.2 | 20.6 |
樹莓派 4B(RT 核心) | 0.9 | 1.2 | 4.2 | 1.0 |
飛騰 2000(RT 核心) | 1.0 | 2.2 | 4.5 | 1.7 |
「表 8 各項資料表明,RT 核心在負載情況下,實時性較為穩定。」
「為確定 Cyclictest 測試的有效性,經過飛騰 2000 平台空載測試 2 天,最大延遲為 58 微秒。」
實時性對系統影響測試
測試環境
表9:測試軟體環境
版本名稱 | 來源 |
openEuler 22.03 LTS 核心 | openEuler 22.03 LTS 官方源 |
openEuler 22.03 LTS 核心 | openEuler 22.03 LTS 官方源 |
表10:硬體測試環境
硬體型号 | 硬體配置資訊 | 備注 |
飛騰 D2000 | CPU:8 核 記憶體:16GB 儲存設備:SSD | 桌上型電腦 |
飛騰 2000/4 | CPU:4 核 記憶體:16GB 儲存設備:SSD | 桌上型電腦 |
表11:測試工具
測試軟體 | 功能 | 版本 |
unixbench | 系統的基準測試工具,可用于測試 CPU、記憶體、磁盤等。測試結果與硬體、系統、開發庫、編譯器等相關。 | 5.1.3 |
lmbench | 是一套簡易可移植的,符合 ANSI/C 标準為 UNIX/POSIX 而制定的微型測評工具。一般來說,它衡量兩個關鍵特征:反應時間和帶寬。Lmbench 旨在使系統開發者深入了解關鍵操作的基礎成本。 | 3alpha4 |
rt-test(cyclictest) | 通過 cyclictest 工具,每項測試 1000 萬次,輸出平均延遲(Avg)和最大延遲(MAX) | 1.00 |
測試結果
- 飛騰 D2000 平台 unixbench 測試結果
使用
unixbench
單個任務測試非 RT 核心空負載、RT 核心空負載、RT 核心負載 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三種狀态詳細測試結果如下(表中“RT/非 RT”、“RT 負載/非 RT”為百分比值,數值越大說明 RT 核心性能越好):
表12:單任務Unixbench測試結果
測試項 | 非 RT 核心 | RT 核心 | RT 核心負載 | RT/非 RT | RT 負載/非 RT |
Dhrystone 2 using register variables | 24920250.9 | 24994936.3 | 25463306.6 | 100.30% | 102.18% |
Double-Precision Whetstone | 4043.3 | 4042.8 | 4042.9 | 99.99% | 99.99% |
Execl Throughput | 2700.1 | 2112.1 | 2109.6 | 78.22% | 78.13% |
File Copy 1024 bufsize 2000 maxblock | 437294.1 | 307416.2 | 303652.3 | 70.30% | 69.44% |
File Copy 256 bufsize 500 maxblocks | 122072.4 | 88889.0 | 86090.9 | 72.82% | 70.52% |
File Copy 4096 bufsize 8000 maxblocks | 995255.5 | 809771.5 | 774228.3 | 81.36% | 77.79% |
Pipe Throughput | 612119.9 | 487314.9 | 482060.0 | 79.61% | 78.75% |
Pipe-based Context Switching | 79151.2 | 65953.5 | 65399.0 | 83.33% | 82.63% |
Process Creation | 5098.4 | 3481.7 | 3367.9 | 68.29% | 66.06% |
Shell Scripts (1 concurrent) | 3907.2 | 3311.8 | 3264.1 | 84.76% | 83.54% |
Shell Scripts (8 concurrent) | 1724.2 | 1199.9 | 1187.6 | 69.59% | 68.88% |
System Call Overhead | 478285.9 | 436596.3 | 434507.4 | 91.28% | 90.85% |
「System Benchmarks Index Score」 | 「773.4」 | 「626.4」 | 「618.5」 | 「80.99%」 | 「79.97%」 |
使用
unixbench
多任務測試非 RT 核心空負載、RT 核心空負載、RT 核心負載 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三種狀态詳細測試結果如下(表中“RT/非 RT”、“RT 負載/非 RT”為百分比值,數值越大說明 RT 核心性能越好):
表13:多任務Unixbench測試結果
測試項 | 非 RT 核心 | RT 核心 | RT 核心負載 | RT/非 RT | RT 負載/非 RT |
Dhrystone 2 using register variables | 199461755.8 | 199159490.6 | 195978301.9 | 99.85% | 98.25% |
Double-Precision Whetstone | 32216.4 | 32308.6 | 32094.1 | 100.29% | 99.62% |
Execl Throughput | 14832.9 | 9786.4 | 9375.0 | 65.98% | 63.20% |
File Copy 1024 bufsize 2000 maxblock | 924225.9 | 107564.5 | 104520.3 | 11.64% | 11.31% |
File Copy 256 bufsize 500 maxblocks | 253687.9 | 27474.4 | 26157.9 | 10.83% | 10.31% |
File Copy 4096 bufsize 8000 maxblocks | 2523753.4 | 415702.5 | 395431.5 | 16.47% | 15.67% |
Pipe Throughput | 4848867.9 | 3771186.3 | 3822723.4 | 77.77% | 78.84% |
Pipe-based Context Switching | 657475.9 | 526984.6 | 522867.1 | 80.15% | 79.53% |
Process Creation | 29117.5 | 11881.7 | 11580.0 | 40.81% | 39.77% |
Shell Scripts (1 concurrent) | 17309.7 | 8265.0 | 8199.6 | 47.75% | 47.37% |
Shell Scripts (8 concurrent) | 2308.1 | 957.1 | 937.3 | 41.47% | 40.61% |
System Call Overhead | 2928882.1 | 2765649.3 | 2744875.5 | 94.43% | 93.72% |
「System Benchmarks Index Score」 | 「3406.4」 | 「1525.8」 | 「1494.4」 | 「44.79%」 | 「43.87%」 |
-
飛騰 D2000 平台 lmbench 測試結果
使用
測試非 RT 核心空負載、RT 核心空負載、RT 核心負載 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三種狀态詳細,測試十次取平均值,結果如下:lmbench
- 表14:多任務Lmbench測試結果
openEuler 22.03 LTS 新特性解讀 | Preempt_RT -
飛騰 2000 平台測試結果
飛騰 2000 平台測試結果與飛騰 D2000 平台測試結果相似度較高,具體資料不在此處列出。
測試結論
「Preempt_RT 更新檔可以有效提高系統實時性,且在多種負載場景下,實時性表現較為穩定。」
「Preempt_RT 更新檔對本地通訊吞吐率有一定影響,主要提現為管道讀寫、檔案拷貝,對系統調用延遲影響大多在 2 微秒以内。」
後續工作
- 跟随核心主線釋出、維護 Preempt_RT 更新檔
- 研發實時性性能分析工具
- 提升實時性
- 提升吞吐率
- 引入 RTLA、RTSL 機制等
主要參與者
特别感謝 Kernel SIG 組XieXiuQi、zhengzengkai,Embedded SIG 組wanming-hu,樹莓派 SIG 組woqidaideshi,QA SIG 組suhang給予我們的幫助。
姓名 | Gitee ID |
郭皓 | guohaocs2c |
馬玉昆 | kylin-mayukun |
張遠航 | zhangyh1992 |