Try   HackMD

2025q1 Homework3 (kxo)

contributed by < HeatCrab >

作業書寫規範:

  • 無論標題和內文中,中文和英文字元之間要有空白字元 (對排版和文字搜尋有利)
  • 文字訊息 (尤其是程式執行結果) 請避免用圖片來表示,否則不好搜尋和分類
  • 共筆書寫請考慮到日後協作,避免過多的個人色彩,用詞儘量中性
  • 不要在筆記內加入 [TOC] : 筆記左上方已有 Table of Contents (TOC) 功能,不需要畫蛇添足
  • 不要變更預設的 CSS 也不要加入任何佈景主題: 這是「開發紀錄」,用於評分和接受同儕的檢閱
  • 在筆記中貼入程式碼時,避免非必要的行號,也就是該手動將 c=cpp= 變更為 ccpp。行號只在後續討論明確需要行號時,才要出現,否則維持精簡的展現。可留意「你所不知道的 C 語言: linked list 和非連續記憶體」裡頭程式碼展現的方式
  • HackMD 不是讓你張貼完整程式碼的地方,GitHub 才是!因此你在開發紀錄只該列出關鍵程式碼 (善用 diff 標示),可附上對應 GitHub commit 的超連結,列出程式碼是為了「檢討」和「便於他人參與討論」
  • 留意科技詞彙的使用,請參見「資訊科技詞彙翻譯」及「詞彙對照表
  • 不要濫用 :::info, :::success, :::warning 等標示,儘量用清晰的文字書寫。:::danger 則僅限授課教師作為批注使用
  • 避免過多的中英文混用,已有明確翻譯詞彙者,例如「鏈結串列」(linked list) 和「佇列」(queue),就使用該中文詞彙,英文則留給變數名稱、人名,或者缺乏通用翻譯詞彙的場景
  • 在中文敘述中,使用全形標點符號,例如該用「,」,而非 ","。注意書名號的使用,即 ,非「小於」和「大於」符號
  • 避免使用不必要的 emoji 字元

開發環境

$ gcc --version
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0

$ lscpu
Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   39 bits physical, 48 bits virtual
CPU(s):                          12
On-line CPU(s) list:             0-11
Thread(s) per core:              2
Core(s) per socket:              6
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           151
Model name:                      12th Gen Intel(R) Core(TM) i5-12400
Stepping:                        5
CPU MHz:                         800.000 (根據 CPU(s) scaling MHz: 18% 和 max/min 推算)
CPU max MHz:                     4400.0000
CPU min MHz:                     800.0000
BogoMIPS:                        4992.00
Virtualization:                  VT-x
L1d cache:                       288 KiB
L1i cache:                       192 KiB
L2 cache:                        7.5 MiB
L3 cache:                        18 MiB
NUMA node0 CPU(s):               0-11

在作業三的 Load Average 說明中提到 Linux 核心計算 load average 的公式是使用指數平滑運算(Exponential smoothing)推導而成的。指數平滑運算公式的公式定義如下:

St=α×Xt+(1α)×St1,where 0<α<1
但是在作業說明中使用的是:
St=α×Xt1+(1α)×St1,where 0<α<1

可以發現兩者在定義實際值

X 的時間點不同,兩個都可以使用,但若是要推導到 Linux 核心使用的公式的話,應該要使用
Xt
而非
Xt1
。原因如下:
Linux 核心在 include/linux/sched/loadavg.h 中使用的公式:

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

active 這個變數根據定義是 'RUNNABLE + TASK_UNINTERRUPTIBLE' Process 總數,也就是 calc_load_tasks 這個全域變數。所以 activenewload 當下時間點的實際值,應該要是

Xt 而非
Xt1

此外,從原本的指數平滑公式推導至 Linux 核心使用的 load averge 公式,我有些疑惑。原本的
α
在指數平滑公式代表的是平滑因子,依據泰勒展開後得到近似值是:
αΔTτ
可是 Linux 核心使用的 exp 變數是
eintervalwindow
,又因為他是定點數,也可以說
exp=α × FIXED_1

那問題就來了,原本的指數平滑公式,
Xt
是直接乘上
α
,而
St1
則是乘上
(1α)
,我的理解是
α
在此處是代表一個權重,如果
α
的值越靠近
1
,則
St
受到
Xt
值的影響越大,反之,
α
越靠近
0
St1
的影響較大。相較於原本的指數平滑公式,Linux 核心使用的公式不是直觀的直接使用原本的指數平滑公式而來的,而是調整了一下 load
(St1)
active
(Xt)
的乘數對像。但是同理來說,如果 exp 的值越靠近
FIXED_1
,則 load 對於 newload 的影響就越大,反之 active 對於 newload 的影響就越大?是這樣子想的嗎?
如果真是這樣,那我會覺得說為什麼要畫蛇添足改變原本的指數平滑公式中定義的乘數對象?
是因為 load 才是 newload 變數影響的主因,所以讓他直接乘上 exp ,而不是如同原本的指數平滑公式一樣直接讓 active 乘上 exp 呢?或是有其他的原因嗎?

後續探討呢?