# 開發紀錄 (1): 環境架設 contributed by < [`charliechiou`](https://github.com/charliechiou) > < [`EricccTaiwan`](https://github.com/EricccTaiwan) > ## 關閉 E-core 電腦的 cpu 版本如果有 12-th 後[大小核](https://www.intel.com.tw/content/www/tw/zh/support/articles/000091896/processors.html),會影響到實驗結果,需要把小核關掉 - 查看大小核 (P/E core) ```shell $ lstopo ``` ![image](https://hackmd.io/_uploads/S14Vs6oyll.png) [二:Intel系列主機板如何關閉CPU部分核心(即E-core)?](https://www.asus.com/hk/support/faq/1054283/#222) ![image](https://hackmd.io/_uploads/HkxB7BA1ex.png=30%x) :::spoiler ```$ $ uname -r 6.14.0-16-generic $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 25.04 Release: 25.04 Codename: plucky ``` ```shell $ neofetch $ lstopo ``` **關閉 E-core 前** - CPU: 12th Gen Intel i9-12900K (24) @ 5.100GHz ![image](https://hackmd.io/_uploads/SyIUqkh1ge.png=30%x) ![image](https://hackmd.io/_uploads/r1aWUAoygg.png=10%x) **關閉 E-core 後** - CPU: 12th Gen Intel i9-12900K (16) @ 5.100GHz ![image](https://hackmd.io/_uploads/r1WKMSAkxg.png=30%x) ![image](https://hackmd.io/_uploads/B1pkQSC1ee.png=30%x) ::: ## 版本及 sched_ext 支援 ### 核心版本要求 [sched_ext is supported by the upstream kernel starting from version 6.12](https://arighi.blogspot.com/search?updated-max=2025-05-01T00%3A17%3A00%2B02%3A00&max-results=1),因此核心版本要求 6.12+,至於 6.13、6.14 的核心版本在 scx 上的表現是否有差異? [Tejun Heo](https://github.com/htejun) (scx 的 maintainer) 給了以下回覆, > There are new features introduced which may improve performance in some cases (e.g. queued_wakeup support) but for the most part, the kernel versions wouldn't cause noticeable differences. All schedulers should work fine across the kernel versions. [name=Tejun Heo] ### 開發環境的核心及 Ubuntu 版本 > 我們將 server 從 Ubuntu 24.04 $\to$ 24.10 $\to$ 25.04 一路向上升級; 如果空間有限,也可用舊版 Ubuntu 搭配 kernel v6.12+ 作為實驗環境 (e.g. Ubuntu 24.04 w/ kernel v6.12) ```shell OS: Ubuntu 25.04 x86_64 Kernel: 6.14.0-16-generic ``` #### 方法一 : 升級至 Ubuntu 25.04 ```shell $ sudo apt update $ sudo apt upgrade $ sudo apt dist-upgrade $ sudo apt install update-manager-core ``` 目前最新的 LTS 為 Ubuntu 24.04,因此需調整升級設定以對應此版本: ```shell $ sudo vim /etc/update-manager/release-upgrades ``` 把最後一列的 `Prompt=lts` 改成 `Prompt=normal`, ```diff [DEFAULT] # Default prompting and upgrade behavior, valid options: # # never - Never check for, or allow upgrading to, a new release. # normal - Check to see if a new release is available. If more than one new # release is found, the release upgrader will attempt to upgrade to # the supported release that immediately succeeds the # currently-running release. # lts - Check to see if a new LTS release is available. The upgrader # will attempt to upgrade to the first LTS release available after # the currently-running one. Note that if this option is used and # the currently-running release is not itself an LTS release the # upgrader will assume prompt was meant to be normal. - Prompt=lts + Prompt=normal ``` 接著執行 ```shell $ sudo do-release-upgrade -d # 開始升級 Ubuntu ``` 升級後檢查是否升級成功 ```shell $ lsb_release -a ``` 由於每次升級僅能跨一個版本,因此若從 24.04 升級至 25.04,需先升級至 24.10,再進一步升級至 25.04,共需進行兩次升級。 #### 方法二 : 僅下載 kernel v6.12 先下載對應的核心檔案 ```shell $ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.tar.xz $ tar -xf linux-6.12.tar.xz $ cd linux-6.12 ``` 接著把原本作業系統中的設定檔複製並編譯 ```shell $ cp /boot/config-$(uname -r) .config $ make menuconfig ``` 編譯核心(可能會花上很多時間) ```shell $ make -j$(nproc) $ sudo make modules_install $ sudo make install ``` 最後更新 grub 並重開機。 ```shell $ sudo update-grub $ sudo reboot ``` 確認升級後的核心版本 ```shell $ uname -r # 要出現 6.12 ``` ### 確認支援 sched_ext 確認目前核心是否支援 sched_ext ```shell $ ls /sys/kernel/ | grep sched_ext ``` 確認目前 sched_ext 的狀態 ```shell $ cat /sys/kernel/sched_ext/state ``` 以 `scx_rustland` 為例(後續會提到如何編譯 `scx_rustland` 並執行)執行 `scx_rustland` 前後輸出結果如下: ```shell $ # Before attached scx_rustland $ cat /sys/kernel/sched_ext/state disabled $ # After attached scx_rustland $ cat /sys/kernel/sched_ext/state enabled ``` ### 下載 sched-ext (簡稱 scx) > [sched-ext/scx: README](https://github.com/sched-ext/scx?tab=readme-ov-file#sched_ext-schedulers-and-tools) 可以參考 [Build & Install](https://github.com/sched-ext/scx?tab=readme-ov-file#build--install),下方以 Ubuntu/Debian 環境為例 #### 1. 下載 `meson` > Note: Many distros only have earlier versions of meson, in that case just clone the meson repo and call `meson.py` > e.g. `/path/to/meson/repo/meson.py compile -C build` . > > Alternatively, use pip e.g. `pip install meson` or `pip install meson --break-system-packages` (if needed). #### 2. 下載 dependencies ```shell $ sudo apt install build-essential libssl-dev llvm lld libelf-dev meson cargo rustc clang llvm cmake pkg-config protobuf-compiler ``` #### 3. Static linking against libbpf (preferred) > 這個方式,C 和 Rust 都可以編譯完成 ```shell $ cd ~/scx $ meson setup build --prefix ~ $ # 以下每次更新 code 完都需要重跑 (編譯前記得存檔) $ meson compile -C build $ sudo meson install -C build $ # $ meson setup --wipe build ## re-config 才需要或是 build 失敗 ``` > meson always uses a separate build directory. Running the following commands in the root of the tree builds and installs all schedulers under `~/bin`. 執行 meson compile 後會把執行檔及中間的建構檔存在對應的資料夾中,若要把可執行的檔案安裝下來則需要使用 meson install 並透過 `-C` 切換到 build 的資料夾中做安裝,而安裝的位置則是前述用 setup 設定的位置 (i.e., `~`)。 接著執行 `sudo ~/bin/<schedule name>` 便可執行對應的 scheduler。 >詳細的安裝步驟可以查看 `meson.build` 的腳本,其中在 `if enable_rust` 的段落中 >```rust > cargo_cmd = [cargo, 'build', '--manifest-path=@INPUT@', '--target->dir=@OUTDIR@', cargo_build_args] >``` >會把 rust 的排程器建構在 `@OUTDIR@` ,而 `@OUTDIR@` 則是由 meson 傳入的 target。 因此也可以在 target 資料夾中的 `release-fast` 中找到我們的 rust 排程器。 另一方面 c 語言所建構的排程器則會安置在 build 資料夾底下。 ## 工具介紹 ### scxtop ```shell $ sudo LC_ALL=C scxtop # 執行 scxtop ``` 會出現下方的 TUI 界面,按下 `q` 即可離開 ![image](https://hackmd.io/_uploads/SJ-5FJyelx.png) 執行 scx 排程器的過程中,按下 `a` 可以儲存 trace 檔案,接著打開 [Perfetto UI](https://ui.perfetto.dev/#!/viewer) ,點選左側的 `Open trace file` 開啟剛剛生成的檔案,便可看到下圖的 CPU 排程結果。 ![image](https://hackmd.io/_uploads/SkAXuJtxge.png) 若不想使用到 `scxtop` 提供的 TUI 介面,也可以利用以下指令生成檔名為 test 的二進制檔 ```shell $ sudo scxtop trace --trace-ms 5000 --output-file test ``` ### Perfetto ![image](https://hackmd.io/_uploads/B1_uY1Felg.png) 詳細的測試分析,可見[開發紀錄 (2): FIFO/RR scheduler](https://hackmd.io/@cce-underdogs/linux-exp2),這邊只介紹幾個重要的參數,同時也是我們踩過的地雷, - [Wall duration](https://blog.csdn.net/f2006116/article/details/107581327) (ms) - 代表一個 Process 的總共持續時間 - Wall Avg duration (ms) - :::warning [代表一個 Process 在被中斷前的平均持續時間,而不是平均的 time slice。](https://hackmd.io/@cce-underdogs/prob-1#Clarification) (這點很重要!!!) ::: - Occurences - Process 執行期間的中斷次數 <!-- ### Perf 參考:[GNU/Linux 開發工具 - 運用 Perf 分析程式效能並改善](https://hackmd.io/@sysprog/gnu-linux-dev/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Flinux-perf) 使用以下指令確認目前 perf 權限 ```shell $ cat /proc/sys/kernel/perf_event_paranoid ``` 若需要修改設定,可藉由以下命令調整: ``` $ sudo sysctl kernel.perf_event_paranoid=<parameter> ``` 該參數的權限值共有四種設定,分別如下: - `2`:不允許執行任何效能量測。但某些用於查看或分析現有紀錄的命令仍然可使用,例如 perf ls, perf report, perf timechart, perf trace - `1`:不允許取得 CPU 事件資料 (CPU events data),但可用 perf stat, perf record 並取得 Kernel profiling 資料 - `0`:不允許存取原始 tracepoint,但可使用 perf stat、perf record 並取得 CPU 事件資料。 - `-1`:開放所有權限,無限制 可以用下列的指令來錄下排程並顯示。 ```shell $ perf sched record $ perf sched timehist -Vw --state ``` --> ## Ref * [Linux 核心專題: CPU 排程器 by vax-r](https://hackmd.io/@sysprog/BJdyxvxX0) * [Linux 核心專題: sched_ext 研究 by otteryc](https://hackmd.io/@sysprog/H1u6D9LI0) * [arighi's blog - Ubuntu 25.04 is now sched_ext ready](https://arighi.blogspot.com/) * [sched-ext/scx](https://github.com/sched-ext/scx) * [eBPF 隨筆(七):sched_ext](https://medium.com/@ianchen0119/ebpf-%E9%9A%A8%E7%AD%86-%E4%B8%83-sched-ext-f7b60ea28976) * [Perfetto Docs](https://perfetto.dev/docs/) * [課程討論區相關文章](https://www.facebook.com/share/p/19MQee4kSX/) <!-- ## FB 好文 :::spoiler 貼文 原文連結 : https://www.facebook.com/share/p/19MQee4kSX/ 或許有人會好奇,跟其他 Linux 核心課程相比,為何開設在成功大學的「Linux 核心設計」重視數學 (例如在課堂要求學員證明級數收斂、解釋泊松分布),甚至有人誤以為授課教師在刁難,但真相是,任何工程議題走到極致後,都會通往數學,而 Linux 核心本身就是多種工程議題的彙整,當然更容易接觸到數學。 以 Linux 核心的 CPU 排程器來說,考慮到雲端運算的需求,CFS 發展一系列 CPU 頻寬控制 (bandwidth control; BWC) 的機制,而這背後就是機率統計、排隊理論所支撐。引述內文: >That is, suppose we have 2 tasks, both specify a p(95) value, then we have a p(95)\*p(95) = 90.25% chance both tasks are within their quota and everything is good. At the same time we have a p(5)p(5) = 0.25% chance both tasks will exceed their quota at the same time (guaranteed deadline fail). Somewhere in between there’s a threshold where one exceeds and the other doesn’t underrun enough to compensate; this depends on the specific CDFs. Linux 核心的 CPU 排程器負責在多個競爭行程間分配處理器時間,其設計目標涵蓋 fairness、效率與回應性。此處 fairness 指在時間尺度上,將處理器時間依比例分配給所有可執行 (runnable) 行程,使其長期累積的運算時間趨近於預期占比。 為實施資源限制,核心引入 CPU 頻寬控制 (BWC) 機制,允許系統管理員為 cgroup 設定明確的 CPU 使用上限。其運作依賴二項參數:每週期允許使用的 CPU 配額 cpu.cfs_quota_us 與週期長度 cpu.cfs_period_us。當某個 cgroup 在一個週期內耗盡配額,該群組內所有行程即會暫停執行,直至下一週期重新取得配額。此機制具確定性,能強制執行所設資源約束。 然而,單靠此類確定性機制,難以充分發揮處理器效能,特別是在行程執行時間變異性高的情況下。此時,排程器設計便與機率統計理論密切相關。實際上,Linux 的 CFS 等現代排程器,普遍內建統計推論機制。排程器透過蒐集歷史執行紀錄,運用指數加權移動平均 (EWMA) 預測未來負載,同時在長期觀察中評估 fairness 是否達成,即各行程獲得的處理時間比例是否合理。 系統中充斥各類隨機事件,例如 I/O 完成、中斷觸發等,排程器需在此等不確定情境下維持反應性與穩定性。 為克服傳統 BWC 帶來的過度保守問題,Linux 排程機制進一步引入具彈性的 Burst (突發) 特性,展現統計導向的設計思想。觀察顯示,行程實際執行時間大多低於其最壞情況執行時間 (Worst-Case Execution Time, WCET)。傳統即時系統分析(如基於 EDF 的可行性檢驗)以 WCET 為保證條件,導致保守的資源預留與低效的資源使用。 Burst 策略主張改以統計分佈描述行程行為,選用第 95 百分位(或其他分位數)所對應的執行時間 $x$ 作為常態配額,取代極端的 $x + e$(即 WCET)。此方式使總體利用率 $\sum x_i / \text{Period}_i$ 降低,可納入更多行程。系統容許行程短期內超過 $x$ 執行(即動用額外額度 $e$),並仰賴其未來執行時間低於 $x$ 以抵銷超額。 此策略不再強求所有截止期限均被滿足。當多個行程同時超出 $x$ 時,系統總需求可能超過處理器上限,導致部分行程逾期。不過,若 $x$ 設定不低於平均執行時間,系統平均負載仍可穩定控制。即使發生逾期,其延遲(tardiness)可受限於總彈性額度 $\sum e_i$,只要 WCET 評估具保守性,便能確保長期行為不發散。 評估 Burst 帶來的實際干擾,特別是對其他使用者的影響,屬於複雜問題。系統中同時存在多使用者、彈性借貸與隨機需求分佈,使傳統工具 (如排隊理論與馬可夫鏈) 難以建構有效模型,因此 Linux 核心開發者轉而採用模擬方法分析其行為。 模擬中,研究者設定 $m$ 個 cgroup 共享 CPU 資源,每組配有相同常態配額與變動大小的 Burst Buffer (以配額倍數 $b$ 表示),平均 CPU 利用率 $u_{avg}$ 為主要參數。各 cgroup 的需求建模為獨立同分佈隨機變數,分佈型態包括指數、泊松與帕累托 (Pareto) 分佈,其中帕累托因其重尾性,適合模擬突發性極高的負載情形。 模擬紀錄兩項指標:違反 WCET 的機率 $P(\text{WCET} > 1)$,即系統在單一週期內無法滿足所有需求的機率;連續違約週期的期望值 $E(\text{WCET})$,即從第一次逾期至恢復正常的週期數。 結果揭示若干趨勢:干擾程度對 $u_{avg}$ 與群組數 $m$ 敏感度極高。在高利用率情境下,系統缺乏彈性緩衝以吸收突發需求,錯誤率顯著提升。若群組數偏少,單一群組的高需求即可能造成過載;反之,群組數多時,各自需求波動彼此抵銷,總體變異性降低,系統更為穩定。相較之下,Burst Buffer 大小 $b$ 的影響較小,特別在低 $u_{avg}$ 或高 $m$ 條件下影響更為微弱。不同分佈型態亦顯著影響行為,帕累托分佈因重尾特性,在高負載下易引發明顯干擾。 據此可提出若干建議:在高負載或僅有少數關鍵群組的系統中,應避免或嚴格限制 Burst Buffer 的使用;而在群組眾多且平均利用率較低的環境下,可適度啟用甚至放寬 Burst Buffer 設定,在不顯著增加風險的前提下提升資源使用效率。 於是,從確定性的 BWC 到統計驅動的 Burst 特性,Linux 排程機制體現對資源效率與可預測性之間微妙平衡的追求。理解 fairness 的技術意涵、掌握機率統計理論並配合模擬方法進行驗證,是發展現代穩健排程策略的關鍵。 https://docs.kernel.org/scheduler/sched-bwc.html ::: -->