owned this note changed 3 months ago
Linked with GitHub

2025-04-08 問答簡記

關稅

各國巡禮

image
美國在過去數十年間一直是世界秩序與全球化的主導力量,而台灣的經濟發展幾乎完全仰賴美國的支持,這一點無可否認。從 1950 年代的美援物資與貸款,到開放市場讓台灣的農產品與輕工業得以累積外匯資本,美國為台灣提供了經濟起飛的基礎。隨後在 1960 至 1970 年代,美國將台灣塑造成全球代工廠之一;1980 年代後,又推動其發展電子產業與半導體製造,融入美國產業鏈。若無這些支持,台灣的發展軌跡可能與菲律賓相差無幾,淪為全球化體系的邊緣地帶。2025 年的世界中,菲律賓的經濟地位難以與台灣相比,但台灣的成就很大程度上源於美國的扶植,而非單純靠自身努力。

台灣在全球化中的重要性始終與美國利益緊密相連。美國可以在不同時期根據自身需求調整對台政策:冷戰末期默許台灣企業率先進入中國,利用改革開放的廉價勞動力;如今則因中國崛起而轉向遏制。美國多次表明,中國統一台灣不符合其利益,因為台灣是美國扶植的區域經濟強權,承載數十年的技術與經濟投資,尤其是半導體產業。放任台灣被中國吞併,等於讓這些投資付諸東流,還拱手送給潛在對手,這是美國任何執政者都無法接受的。事實上,台灣從種香蕉的農業國轉型為半導體強國,靠的是美國的市場與技術支持,而非單純的內生動力。

政治站隊是台灣成功的核心。若當初選擇蘇聯為首的東方陣營,台灣再努力也難逃邊緣化命運。反觀中國,儘管在半導體等领域投入巨大,因地緣政治受限,難以突破美國封鎖。台灣則因接受附庸角色,得以在美國庇護下發展。川普的互惠關稅政策凸顯這一現實。這項以貿易逆差為基礎的策略,表面上平衡赤字,實則圍堵中國並重塑供應鏈。中國透過洗產地滲透美國市場,迫使川普將壓力轉嫁各國,逼其上談判桌證明對抗中國的立場。對台灣而言,這既是挑戰也是機遇。若能清理中資偽裝的洗產地公司,建立透明輸美供應鏈,或許能與美國達成雙邊貿易協定,成為可信賴的供應鏈核心。

美國從二戰後的製造大國轉型為消費大國,其國策塑造了今日全球化格局。當初將高成本製造業外移,意外養大中國這一競爭者。如今川普試圖扭轉局面,但製造業回流並不現實,其真正目標是迫使盟友共同防堵中國。台灣身處中美博弈前線,選擇有限,只能緊跟美國步伐。當美國投資中國時,台灣隨之進入;當美國撤離時,台灣亦須配合。面對關稅壓力,台灣若不順應美國政策,恐被列入打擊對象。台灣的國際地位取決於美國,而非自身,這是經濟與政治現實。憑藉半導體等優勢,台灣需在談判中尋求最大利益,方能在這場變局中找到生存之道。

回顧

2025-04-01 問答

歐拉數: 用積化和差公式和三角函數表進行間接乘法 \(\to\) 對數表 \(\to\) 指數函數 \(\to\) 描述連續成長和衰變 \(\to\) 機率統計 \(\to\) 描述 CPU scheduler 行為

HenryChaing

TASK_READY 沒必要存在。

biometric ,audio / video synchronization - real-time

Multilevel-Feedback Queue

Figure 2.1 sequence

class 對應 policy -> 不同的病患要有不同處理方式

set_schedule (2)

select: I/O multiplexing
CPU scheduler: time multiplexing
STOP-task: e.g., ftrace

devarajabc

排程器如何支援多核系統?相較於單核要考量哪些問題?

四核的系統有幾個作業系統

HeatCrab

作業三 kxo

關於 Linux Load Average 公式的疑惑

Load Average 說明中,提到 Linux 核心計算 load average 的公式是基於指數平滑運算(Exponential Smoothing)推導而來。標準的指數平滑公式定義如下:

\[ S_t = \alpha \times X_t + (1 - \alpha) \times S_{t-1}, \quad \text{where } 0 < \alpha < 1 \]

然而,作業說明中卻寫成:

\[ S_t = \alpha \times X_{t-1} + (1 - \alpha) \times S_{t-1}, \quad \text{where } 0 < \alpha < 1 \]

這兩者在實際值 \(X\) 的時間點上有明顯不同。雖然在某些特定情境下,兩種寫法可能都適用,但我認為若要推導到 Linux 核心實際使用的公式,應該採用 \(X_t\) 而不是 \(X_{t-1}\)。我的理由如下:

在 Linux 核心的 include/linux/sched/loadavg.h 中,計算 load average 的公式是:

newload = load * exp + active * (FIXED_1 - exp);

這裡的 active 根據定義是「RUNNABLE + TASK_UNINTERRUPTIBLE」的行程總數,也就是全域變數 calc_load_tasks 的值。換句話說,active 代表的是當前時間點的實際活動行程數,也就是 \(X_t\),而不是前一時間點的 \(X_{t-1}\)。既然如此,為什麼作業說明會用 \(X_{t-1}\) 呢?我覺得這可能是一個疏忽,因為從程式碼來看,active 確實是當下的數據,應該對應到 \(X_t\) 才合理。

從標準公式到 Linux 公式的推導疑問

再來,我對標準指數平滑公式如何推導到 Linux 核心的版本有些困惑。在標準公式中,\(\alpha\) 是平滑因子,根據泰勒展開的近似值可以寫成:

\[ \alpha \approx \frac{\Delta T}{\tau} \]

但 Linux 核心用的 exp 卻是 \(e^{-\frac{\text{interval}}{\text{window}}}\),而且因為它是定點數表示,可以說:

\[ exp = \alpha \times FIXED_1 \]

這裡的 FIXED_1 是定點數的單位值(通常是 2048)。標準公式中,\(X_t\) 直接乘以 \(\alpha\)\(S_{t-1}\) 乘以 \((1 - \alpha)\),我的理解是 \(\alpha\) 在這裡扮演權重的角色:當 \(\alpha\) 越靠近 1,\(S_t\) 就越受當前值 \(X_t\) 的影響;反之,\(\alpha\) 越靠近 0,\(S_t\) 就越依賴前一時刻的 \(S_{t-1}\)

可是,Linux 核心的公式卻變成:

  • load(即 \(S_{t-1}\))乘以 exp
  • active(即 \(X_t\))乘以 (FIXED_1 - exp)

這跟標準公式的乘數分配完全相反!如果按照標準公式的邏輯,當 exp 越大(越靠近 FIXED_1),load 的影響應該越大,而 active 的影響應該變小才對。可是在 Linux 的公式裡,exp 越大時,newload 反而更偏向 load(即 \(S_{t-1}\)),而 active(即 \(X_t\))的影響變小。這跟我對權重的直觀理解好像顛倒了,是我哪裡想錯了嗎?

為什麼要調整乘數對象?

如果我的分析沒錯,那問題就來了:為什麼 Linux 核心不直接沿用標準指數平滑公式的形式,而是刻意調整了 loadactive 的乘數對象?我猜可能是因為 load(前一刻的 load average)被認為是 newload 的主要影響因素,所以讓它乘以 exp,而 active 只扮演輔助角色,乘以 (FIXED_1 - exp)。但這樣的調整感覺有點「畫蛇添足」,因為標準公式已經很直觀了,直接套用不就好了嗎?

還是說,這背後有什麼更深的設計考量?比如說,Linux 核心想要讓 load average 更穩定,所以刻意加大過去值的權重?或者這跟定點數的實現方式有關?

\(\to\) Brendan Gregg 撰寫相當有趣的文章〈CPU Utilization is Wrong〉,指出「CPU Utilization(CPU 利用率)」這個名詞可能有誤導性,並在文中示範數個實驗,顯示其可能帶來的誤解。

根據作者的實作與 perf 腳本,得到的啟發:

「可透過額外度量指標,例如每週期指令數(IPC, instructions per cycle),更清楚瞭解 %CPU 的意義。若 IPC < 1.0,通常表示記憶體(memory)成為瓶頸;若 IPC > 1.0,則可能代表指令管線對 CPU 週期的使用更密集,也就是指令本身變成系統關鍵。」
「所有顯示 %CPU 的效能監控產品(也就是幾乎所有產品)也應同時提供硬體效能計數器(PMC)指標,用以解釋 %CPU 值的含義,而非只給出容易誤導使用者的數字。比方說,可搭配 IPC,或比對『已退休指令週期』與『停滯週期(stalled cycles)』的比例,來判斷系統正在等待什麼。」

perf 計算多執行行程式的 IPC 時,容易犯下重大錯誤,未能如實呈現多行程/多執行緒因同步(synchronization)而產生的停滯時間。我們也打算在撰寫教材時加入這部分內容。

CPU load average(CPU 負載平均值)代表在一段時間內,系統中處於 READY(就緒)狀態的行程(thread)數量平均值。假如某應用程式同時存在大量行程,load 就會顯示得相當高;反之若行程數量不多,load 便相對較低。

CPU Utilization(CPU 利用率)則代表 CPU 的忙碌程度。一般希望每個核(per core)的 CPU 利用率維持在 70% 以下,才能保證系統穩定運行;這個利用率從 0% 到 100% 不等,但若系統包含多核,加總百分比可能超過 100%(例如 4 核最多可達 400%)。

先只討論 "load" 與 "utilization",暫不深入 IPC,因為常見工具(如 topmpstat)並不直接顯示 IPC,而且 IPC 也無法全面展現整個系統狀態。

CPU 利用率可分為「時間導向(time-based)」與「容量導向(capacity-based)」兩類。Linux 採用時間導向,也就是「非 idle time」:凡是 CPU 未執行 idle thread(閒置行程),便視為 CPU 忙碌。

因此,若處理器耗費許多週期在等待 cache miss(記憶體存取),這些週期仍被視為 CPU 忙碌,而非 idle。即使指令處於停滯,也仍算作非 idle time,因而納入 CPU 利用率。Brendan Gregg 的文章中有一張示意圖,區分 idle(空轉)、busy(忙碌)與 stalled(停滯)三種狀態:
image

在 Linux 系統常用 mpstat 來即時查看各核的 user time、sys time、idle time 等,再進一步推算 CPU utilization。

「load average(負載平均值)」的定義在 Linux 與其他作業系統之間略有差異。Brendan Gregg 的文章〈linux load average〉探討 Linux load average 的演進,並回溯到 1993 年的相關 patch。

「在 Linux 中,負載平均值(load averages)是『系統負載平均值』,衡量整個系統層面所有正在執行或等待執行(CPU、磁碟、或不可打斷鎖等待)的行程數量。換言之,只要不是完全空閒的行程,都納入統計,這也涵蓋對不同資源的需求。」
「在其他作業系統裡,load average 可能更多地是『CPU 負載平均值』,只計算執行中或可執行(runnable)的行程。好處是更易理解 CPU 純粹執行方面的忙碌程度。」

因此,Linux 會將 TASK_UNINTERRUPTIBLE 的行程也統計在內,例如正在等待磁碟 I/O 的程式。若只統計執行中或可執行的行程,可能導致磁碟 I/O 極度瓶頸的系統顯示極低的 runnable threads 平均值,卻實際相當緩慢。

在 Linux 中,可用 uptimetop 查看 load average(1 分鐘、5 分鐘、與 15 分鐘平均)。

Load 與 PELT

  • Linux 在排程時,使用 PELT(Per-Entity Load Tracking)對每個 cgroup 或每個行程的負載進行更細緻的衡量,並動態調整排程決策
  • load average 偏向長期平均的系統監控,觀察一段時間內就緒行程或等待資源行程的數量
  • PELT 的時間尺度較短,著重即時排程
  • Cgroup 可透過 CPU controller 等機制讀取 PELT 負載,用於設定配額或權重

在計算 load 時,Linux 會把不可打斷等待(uninterruptible)行程也考慮,而 PELT 聚焦可排程(runnable)狀態,兩者衡量目標與週期並不相同。再者,只要某個 kthread 處於 runnable/uninterruptible 狀態,Linux 便會將其納入 load,而在 cgroup 的 PELT 機制下,仍需看實際配置而定。

延伸閱讀

Select a repo