名詞解釋 #
1. NUMA (Non-Uniform Memory Access,非均勻記憶體存取) #
- 🍡解釋 : 一種多處理器的記憶體架構,不同處理器存取記憶體的存取時間不相同。處理器存取本地記憶體較快,存取其他處理器的記憶體較慢。
- 🍥舉例 : 想像一個大辦公室有兩個團隊(兩個處理器)
- 本地記憶體: 放在你手邊桌上的文件,拿起來讀非常快。
- 遠端記憶體: 放在隔壁團隊桌上的文件,你要走過去拿,花的時間比較久。
- NUMA 的意義就是告訴系統:「盡量用自己桌上的文件,不要一直跑去隔壁桌拿。」
2. Processor Affinity (處理器親和性 / CPU Affinity) #
- 🍡解釋 : 指作業系統將行程或執行緒綁定在特定處理器上執行,以減少處理器切換並提高快取命中率,進而提升效能。
- 🍥舉例 : 想像一位廚師(行程)在 1 號流理台(CPU 1)切菜。
- 有親和性: 廚師一直待在 1 號台,他的刀具、砧板、切好的菜(Cache 快取資料)都在手邊,工作效率極高。
- 沒有親和性: 經理突然叫廚師換到 2 號流理台。他得重新把刀具搬過去、重新適應環境,這段時間就是效能損耗。
3. Critical Section (臨界區段) #
- 🍡解釋 : 程式中存取共享資源的程式碼區段,同一時間只允許一個執行緒進入,以避免競爭條件並確保資料一致性。
- 🍥舉例 : Critical Section 就像是一台提款機(共享資源)。
- 如果是夫妻共用一個帳戶,兩個人同時在不同提款機想領光餘額(進入 Critical Section)。
- 如果沒有鎖定機制,兩個人可能同時看到餘額充足,同時領出現金,導致銀行帳目錯誤(競爭條件 Race Condition)。
舉一個例子,比如這段程式 x=x+1,假設初始值 x = 0。這行程式碼在 CPU 底層其實分為三個動作: :
- LOAD: 記憶體讀取
x到暫存器。 - ADD: 在暫存器將值 +1。
- STORE: 將結果寫回記憶體 x。
好玩的來了,若兩個行程 (Process A, Process B) 同時執行,可能發生以下交錯 (Interleaving):
| 時間 | 行程 A(Process A) | 行程 B(Process B) | x 的記憶體值 | 備註 |
|---|---|---|---|---|
| T1 | 拿 x(讀到 0) | 0 | A 準備運算 | |
| T2 | 拿 x(讀到 0) | 0 | 關鍵點!B 也讀到舊的值 | |
| T3 | 把 x + 1(變 1) | 0 | A 在自己的暫存器算完 | |
| T4 | 把 x + 1(變 1) | 0 | B 在自己的暫存器算完 | |
| T5 | 放回 x(寫入 1) | 1 | A 更新結果 | |
| T6 | 放回 x(寫入 1) | 1 | 錯誤!B 覆蓋了 A 的結果 |
- 預期結果:執行兩次
+1,x應該要是 2。 - 實際結果:因為 B 在 A 寫入前就讀到了舊值,導致 A 的計算被覆蓋,
x變成了 1。 - 結論:這段
x = x + 1的程式碼就是 Critical Section,必須加上鎖 (Lock) 讓它們排隊執行。
4. Spin Lock (自旋鎖) #
- 🍡解釋 : 一種鎖定機制,執行緒在無法取得鎖時不會進入睡眠狀態,而是持續忙等直到取得鎖為止,適用於臨界區段很短的情況。
- 🍥舉例 : 想像你在排公共廁所。
- Spin Lock: 你站在門口,每隔一秒就敲門問:「好了嗎?好了嗎?」(忙等 Busy Waiting)。這很累人(浪費 CPU),但裡面的人一出來你就能馬上進去(反應快)。
- 一般 Mutex(睡眠鎖): 你去旁邊椅子上睡覺,請裡面的人出來後叫醒你。這省力(不浪費 CPU),但被叫醒需要時間(Context Switch 開銷)。
5. Logical address (邏輯位址) #
- 🍡解釋 : 程式在執行時由 CPU 產生的位址,屬於行程可見的虛擬位址。
- 🍥舉例 : 程式中存取變數
x時,CPU 產生位址0x00000721,這就是邏輯位址。
6. Physical address(實體位址) #
- 🍡解釋 : 實際在主記憶體(RAM)中的位址,由 MMU 將邏輯位址轉換而來。
- 🍥舉例 : MMU 將邏輯位址
0x00000721轉換成實體位址0x1A114544,實際存取 RAM。
邏輯位址和實體位址的關係差不多是這樣子 :
(產生) (轉換) (存取)
CPU ──────────> 邏輯位址 ──────────> MMU ──────────> 實體位址 ──────────> RAM
(0x00000721) (0x1A114544)
7. Fragmentation(碎片) #
- 🍡解釋 : 記憶體空間被零散切割,導致可用空間無法有效利用的現象。
- 🍥舉例 : 記憶體中有很多小空洞,但沒有連續空間能配置 100KB,造成無法配置。
- 🍶補充 : 碎片又分成
- Internal Fragmentation (內部碎片)
- 解釋 : 當作業系統分配給行程的記憶體區塊 (Block/Frame) 大於行程實際所需的空間時,該區塊內部剩餘未被使用的空間即為內部破碎。簡單理解就是分配的空間遠大於實際使用的空間。
- External Fragmentation (外部碎片)
- 解釋 : 當系統中總剩餘空間足夠容納新的行程,但這些空間是不連續的分散區塊,導致無法滿足該行程的記憶體需求。簡單理解是明明空間夠大,但因為過於分散,導致找不到一塊連續的空間塞進去。
- Internal Fragmentation (內部碎片)
8. Paging(分頁) #
- 🍡解釋 : 將虛擬記憶體分成固定大小的 page,實體記憶體分成 frame,以 page 對 frame 進行對應。
- 🍥舉例 : 程式大小 10KB,被切成 3 個 4KB 的 page,分別放在不同的 frame 中。
簡單示意圖 :
[邏輯記憶體] [分頁表] [實體記憶體]
(Logical Memory) (Page Table) (Physical Memory)
┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ Page 0 │ ──────────> │ 0 ➡ 2 │ ──┐ │ Frame 0 │
├──────────────┤ ├────────────┤ │ ├──────────────┤
│ Page 1 │ ──┐ │ 1 ➡ 0 │ │ │ Frame 1 │
├──────────────┤ │ └────────────┘ │ ├──────────────┤
│ Page 2 │ └───────> (索引 p 查 f) └──────> │ Frame 2 │
└──────────────┘ └──────────────┘
(固定切分) (固定切分)
9. TLB(Translation Lookaside Buffer) #
- 🍡解釋 : 快取頁表轉換結果的高速快取,用來加速位址轉換。 (PS : TLB 是硬體)
- 🍥舉例 : CPU 查詢 TLB 命中頁號 5,直接得到對應 frame,省去查頁表的時間。
示意圖 :
(PS : 我是不是應該考慮一下用 Mermaid 來製圖 ?雖然我是直接叫 Gemini 產生文字示意圖)
(1. 發出邏輯位址 p, d)
CPU ────────────────────────────┐
│
▼
┌─────────────┐
┌───> │ 查詢 TLB │ ────(2. Hit! 命中)───┐
│ └─────────────┘ │
│ │ │
(3. Miss 未命中) │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 查 Page Table│ │
(4. 更新) │ (在 RAM 中) │ │
│ └──────┬──────┘ │
└────────────┘ │
│ (5. 取得 Frame 號碼 f) │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 組合實體位址 │ ───────────> │ 存取實體 RAM │
│ (f, d) │ └─────────────┘
└─────────────┘
- 圖解說明 :
- 快路徑 (Hit): CPU 先查 TLB,如果有紀錄,直接拿到 Frame 號碼,不用訪問 RAM 查表(省下一次 RAM 存取時間)。
- 慢路徑 (Miss): TLB 找不到,只好去 RAM 裡面的 Page Table 慢慢查,查到後順便更新 TLB,下次再用就快了。
10. Reentrant code(可重入程式碼) #
- 🍡解釋 : 可被多個行程或執行緒同時安全執行,不會互相干擾的程式碼。
- 🍥舉例 :
strlen()函式不使用全域變數,可被多個執行緒同時呼叫。
11. PTBR(Page Table Base Register) #
- 🍡解釋 : 儲存目前行程頁表起始位址的暫存器。
- 🍥舉例 : 行程切換時,作業系統更新 PTBR 指向新行程的頁表起點。
12. PTLR(Page Table Length Register) #
- 🍡解釋 : 儲存頁表長度,用來檢查頁號是否合法。
- 🍥舉例 : 程式使用頁號 20,但 PTLR 顯示頁表長度只有 16,判定為非法存取。
13. Demand Paging(需求分頁) #
- 🍡解釋 : 頁面只有在實際被存取時才載入記憶體的分頁策略。
- 🍥舉例 : 程式啟動時只載入主程式,其他函式在被呼叫時才載入記憶體。
14. Page Fault(分頁錯誤) #
- 🍡解釋 : 行程存取的 page 不在記憶體中,需由作業系統從磁碟載入 (會觸發中斷 : Page Fault Trap)。
- 🍥舉例 : 程式第一次存取某 page,但該 page 不在 RAM,觸發 page fault。
15. Copy-on-Write(寫入時複製) #
- 🍡解釋 : 多行程共用同一頁面,直到其中一方寫入時才進行複製。
- 🍥舉例 :
fork()後父子行程共用頁面,子行程修改資料時 (exec()) 才複製該 page。
16. Page Replacement(頁面置換) #
- 🍡解釋 : 當記憶體滿時,選擇一個 page 換出以載入新 page 的機制。
- 🍥舉例 : 記憶體已滿,系統用 LRU ( 一種分頁置換演算法 )將最久未使用的 page 換出。
17. Frame(頁框) #
- 🍡解釋 : 實體記憶體中固定大小的區塊,用來存放 page。
- 🍥舉例 : 實體記憶體被切成多個 4KB 的 frame,每個 frame 可存一個 page。
18. Thrashing(輾轉現象) #
- 🍡解釋 : 系統大部分時間都在處理 page fault,導致效能急劇下降。
- 🍥舉例 : 系統同時執行太多行程,幾乎每次存取都發生 page fault。PS : 或 RAM 不夠大也會發生。
19. Working Set(工作集合) #
- 🍡解釋 : 行程在一段時間內實際頻繁使用的 page 集合。
- 🍥舉例 : 程式在迴圈中反覆使用 page 2、3、5,這些 page 就是其 working set。
20. segmentation(分段) #
- 🍡解釋 : 將程式依照邏輯結構(如程式碼、資料、堆疊)分成大小不固定的 segment 來進行記憶體管理。
- 🍥舉例 : 一個行程被分成 code segment、data segment、stack segment,每個 segment 有不同的大小與存取權限。
21. Semaphore(信號量) #
- 🍡解釋 : 一種同步機制,用整數值與
wait/signal操作來控制多行程或執行緒對共享資源的存取。 - 🍥舉例 : 設定 semaphore 初值為 1,確保同一時間只有一個執行緒能進入 critical section。
22. Dynamic Linking(動態連結) #
- 🍡解釋 : 程式在執行時才將所需的函式庫載入並連結,而非在編譯時完成。
- 🍥舉例 : 執行程式時才載入共享函式庫(如
.so或.dll),多個程式可共用同一份函式庫。