--- robots: index, follow tags: NCTU, CS, 共筆, OS description: 交大資工課程學習筆記 lang: zh-tw dir: ltr breaks: true disqus: calee GA: UA-100433652-1 --- 作業系統概論 -- 張立平 === :::warning 傳教 ::: {%youtube 2_VFKqw1q2Q %} [ppt / 考古題](https://hackmd.io/KK1QfVGPRPa-bH6lXx1_IQ) [2017 OS note](https://hackmd.io/lZTrfFFaQ0ucI7QQGY9eGQ) [中正資工 OS](https://groups.google.com/forum/?hl=zh-Hant#!forum/ccu_os_2018) > 這個網路論壇已經不存在或沒有存取權 QQ ## Syllbus - 上課會抽人問問題 - 7-8 次作業 - 期中/期末 ## Ch1. Introduction ### What is an operating system - 使用者與電腦硬體中間幫忙互動的 intermediary program - Goals: - execute: 幫忙執行使用者的程式 - convenient: 讓使用者更便利的使用 - efficient: 效能 - Computer System Structure (分四層) - Hardware - OS: 控制與讓硬體跟 app 合作 - Application - User ![](https://i.imgur.com/KKJo0hY.png =400x) - OS 的定義 沒有一個明確的定義 - 資源配置者 - 效能 vs 公平 - 是一個控制程式 - control / monitor - 避免錯誤或**不當使用** - 訂購操作系統時供應商所提供的一切 - 電腦開機時始終會執行的東西 - kernel - UNIX OS = kernel + system programs ### IO Structure - IO Hardware - IO devices - [concepts](https://sls.weco.net/node/21333): - Port: - CPU 只要對特定的 port 做讀寫界可以操作 IO - ex. 320 - 32F: disk IO - ![](https://i.imgur.com/BoSmpfD.png =300x) - Bus - daisy chain - CPU處理多個同時中斷要求主要有三種方法之一 - Daisy Chaining / Pulling / Independent Requesting - shared direct access - Controller (host adapter) - IO instructions control devices - devices address - Direct IO instructions - Memory-mapped IO (load / store) - ![](https://i.imgur.com/aeApjuc.png =400x) - 傳統看法: Processor 是 OS 的中心 - 近年有另外一說: Memory 才是 OS 的中心 - PC Organization ![](https://i.imgur.com/IWrEeP3.png =250x) - 北橋 (memory hub) - CPU - Memory - High-Speed devices (ex. GPU) - 南橋 (IO hub) - IO - Network - USB - HD - ... - IO Operation - IO 與 CPU 同時運作 - device controller 有 local buffer - CPU or DMA 處理 device buffer 與 memory 間的 data 移動 - IO 對 CPU 很慢 - polling - CPU 等 IO 處理完後再往下執行 - busy-waiting: CPU 沒有意義的等待 or 檢查一件事情 - interrupt - IO device 主動告知執行完,執行期間 CPU 可以處理其他事情 (DMA) - interrupt-request - 可以被 ignore 或 delay (mask) - 常見功能: - 錯誤處理 - 進入 kernel mode - timer - 過程: - 將 interrupted instructure 存進 memory (之後才能回來繼續執行) - 同時只能執行一個 interrupt 事件 - trap: 觸發 by 軟體 - IRQ: 觸發 by 硬體 - Interrupt Handling - 保護 CPU 目前的 state 需要把 registers 與 PC(program counter) 存入 memory - 決定哪一種 interrupt,跳到相對應的動作 (Interrupt vector table) - ![](https://i.imgur.com/DZiLM8f.png =250x) - Direct Memory Access - 需要快速的 IO 會將它放到離 CPU/memory 較近的地方 - ex. PCI: GPU 現在離 CPU 越來越近了 - ![](https://i.imgur.com/mPurP6d.png =500x) - ex. disk 進 memory 由誰來做? - CPU? 會汙染 cache,不適合來做這種東西 - device (DMA) - Synchronous / Asynchronous IO - Sync: - 在 IO 開始後,process blocking 住,只有在 IO 結束後才會繼續 - blocking 不代表 CPU 會 hang 住,而是會讓 process 進入 waiting mode 而被 preempt 到其他 process - ex. read() / fread() / fsync() (一個會確定都寫入才繼續的 sys call) - Asyn: - IO 開始後,control 回到 program 繼續執行,不會等待 IO 結束 (non-blocking) - ex. IO writing (without O_SYNC) write() / fwrite() / aio_read() (多讀入) - PS. 寫入時,data 會進入 buffer,程式可以繼續,but data 何時進入 file 就不一定了 ### Memory / Storage structure ![](https://i.imgur.com/wodYZWO.png =500x) - Memory Hierarchy - Main memory - large / volatile - RAM (random access) - Secondary storage - nonvolatile / no random access - Storage Structure - hierarchy 階層式 - Caching (快取) - 從較慢的 storage 複製到較快的 storage - access 時會先檢查 cache,如果有就用,沒有就先複製到 cache 在用 - cache 比 main storage 小 - 需求 - 更有效的 lookup service - replacement policy 減少 cache miss - ![](https://i.imgur.com/PsEy3uB.png =400x) ### Operating-System structure - 電腦開機 - Bootstrap program - 開機時載入 - 存在 ROM 或 EEPROM(firmware) - load OS kernel - BIOS + MBR / UEFI + GTP - Multiprogramming - 同時載入多個 job - 單一使用者不可長時占用 CPU / IO - 對單一 Job 來看,只有 OS 和自己 - Timesharing (multitasking) - 程式可以交錯執行 - knowage: - process - CPU scheduling - swapping - virtual memory - etc. - 差別 - Multiprogramming - 多工,同時載入多個 job 進 main memory - (不一定可以同時執行/分時多工/interrupt) - Multitasking - Job 可交錯執行 - 不一定適用 timesharing 方式分工 - Timesharing - 一定要有 timer,會 interrupt - multitasking + periodic switch - Multiprocessing - 一個機器有多個 processor - Dual Mode Operations - user space -> kernel space - Interrupt 為硬體驅動 - exception or trap 為軟體造成 - 硬體(CPU) 需要支援 - 把控制權轉移到 kernel - 可以讓 OS 自我保護並保護其他 component - ![](https://i.imgur.com/IJBOWoI.png =500x) ### Three Pillars - Process Management - process 是指執行中的 program - 需要資源 - CPU time - IO - files / data storage - Scheduling - create / delete / suspending / resuming - communication - synchronization (多 process 時) - deadlock handling - Memory Management - 少數 CPU 可以直接 access 的地方 - 從有 data / instruction - 操作 - allocating / deallocating => memory fragment (記憶體破碎) - swapping / paging - protection (追蹤哪段 mem 是哪個 proc 正在使用) - Storage Management - OS 統一邏輯的看到 (file style) - logical storage -> abstract physical properties - file-system management - accessw control - 操作 - create / delete - read / write - mapping 從 secondary storage 到 main memory - Mass Storage management - IO Subsystem - buffing - caching - spooling (後台 ex. printer) ## Ch2. System Structures - 提供 Service - User Interface - GUI - CLI - Program execution - IO - File system - Communications - Error detection - efficient - ![](https://i.imgur.com/4tugPGZ.png =500x) ### OS user interface - CLI - shell - GUI - 所視即所得 - touchscreen ### System Call - programming interface - 多是被包裝好的 high level API (Application Program Interface),而不會直接呼叫 - 軟體抽象化 - 可攜性、簡單性 - (早期是用組語直接呼叫) - ex. WIN32 API, POSIX API, Java API - Implementation - Interrupt 通常會帶入一個中斷編號 - system-call interface 會維護 interrupt vector table 來查找 中斷編號 的意義 - app 不需要知道 system call 實作方法 - Dual Mode Operation - trap - kernel <-> user mode - 可以保護系統與其他使用者/元件 - 硬體提供 mode bit - system call 只有在 interrupt 完後,進入 kernel mode 才開始執行 - ![](https://i.imgur.com/osO5c03.png =350x) ![](https://i.imgur.com/4AnGTXI.png =250x) - 參數傳遞 (三種方法) - by registers - 存在 memory 的 block 或 table,再傳遞 memory address - push 進 stack - system call 種類 - process control - file management - device management - information maintaenance - communications ### OS design and implementation - goals / spec. - user goals - system goals - hardware / type of system - different goals: - ex. RTOS (Real-time OS): 時間預測性,低延遲 - ex. Mainframe OS: 帶寬,公平性 - 原則 - mechanism: 決定如何做 - policy: 決定下一個該做哪個 job ### OS Structure ![](https://i.imgur.com/Nb14JgM.png =200x) - Simple Structure - ex. MS-DOS / IoT - 沒有 modules 的設計 - 快 - 沒有保護,應用程式可以直接 access hardware - 沒有 dual mode (user / kernel mode) => 不用 system call / interrupt => 快 - 系統錯誤 (ex. 記憶體使用錯誤) 會造成整個系統 crash - UNIX -- monolithic - 目前最受歡迎的架構 - 分兩部分 - systems programs - ex. binutils, cc, as, ld - ![](https://i.imgur.com/DeWgUUT.png =300x) - kernel - kernel 中沒有再明確的架構區分 - ![](https://i.imgur.com/1x2G7or.png =300x) - Layered Approach - 目前沒有 OS 把它實作出來 - debug 與 scale 都很方便 - layer 是很難定義的 - 程式間的 depandency 太高 - ex. storage controler 需要 memroy,但是 memory 需要 storage 做 swapping - ![](https://i.imgur.com/xQ21fKd.png =300x) - modulize - 再過去,需要加入新的 device 時,需要將 device driver code patch 進 kernel code,才能載入,重新開機後才能執行 - module 將 driver code 事先就 compile 進 kernel 帶是沒有載入,只有當硬體插入後,才會 load 進 kernel - `.ko`: kernel object - Microkernel system - 上面的 kernel 東西太多了,希望只把有必要的東西放進 kernel,其他的東西都放到 service (user space) - message passing: 不同 app 溝通 - 好處 - 更容易加功能 - 移植更簡單 - 可靠 / 安全 - Monolithic 所有 sys call 都可能是漏洞,Microkernel 的 sys call 很少 - 缺點 - message pass 都要中斷返回,解資料是用 copy/shared memory 的 - ex. windows NT 3.5 - ![](https://i.imgur.com/94bG90b.png =300x) - ![](https://i.imgur.com/MNomyFf.png =400x) - Virtual Machine - layered approach (分層) - 虛擬化的硬體 (hypervisor) - 需要將 phy hardware 分享給 VM 使用 - 可以提供 isolate - guest OS 與 host OS 的 CPU instructure set 相同 - ![](https://i.imgur.com/VnCyJSw.png =300x) ![](https://i.imgur.com/wmvkVjZ.png =300x) ## Ch3. Processes-Concept ### Concept - A program in execution 執行中的程式 - 包含 - text section - program counter - stack - data section - heap - ![](https://i.imgur.com/zspUtCN.png =100x) - Process State Process 不可能一直在 CPU 上工作 - new - running - ready - waiting - terminated - ![](https://i.imgur.com/givDx3V.png =500x) - State Changage - Running -> waiting - IO / event waiting - Running -> Ready - timer interrupt - 有高 priority process 進入 ready,進而 搶佔 進 running - Waiting 不會直接進入 Running - Process Control Block (PCB) - 每個 process 有關的資訊 - process state - registers value - CPU scheduling info. (ex. priority) - Mem-management info. - ex. segment table - ex. page-table base register - Accounting info. (quota) - IO status - ![](https://i.imgur.com/tgKR2tK.png) - Context Switch - 將 CPU 的執行焦點轉移 - CPU switch to another process - OS 需要儲存 old process 的 state - switch 時 CPU 不能使用 - Context Switch 一定要用組語來寫 - ![](https://i.imgur.com/5qTJOA0.png =300x) ### Process Scheduling - Scheduling Qqueu - Ready queue - Device queue (等待 IO) - Event queue (等待 event ex. semaphore) - schedule 種類 - long-term scheduler (job scheduler) - 哪一個 process 該進入 ready queue - 不常見,以秒/分為單位 - server - 控制 degree of multiprogramming - 兩種 bound 的 process 合理的混合載入 memory 做 multiprogram - 適用 batch-processing systems - PC (timesharing system) 不該使用 long-term - 會物理限制 degree of multiprogramming - 如果使用者長時間搶占不到 CPU... - short-term scheduler (CPU scheduler) - 發生頻率高 => 效能要好 => 最好是 O(1) / O(log) - 哪一個 process 該接下來使用 CPU - timer interrupt - Medium term scheduling - 觀察是否有長時間 waiting 的 process,將它的 memory swapout 到 disk - ![](https://i.imgur.com/cvDTrTP.png =400x) - Process 可分為 - IO bound - 大多數時間在等待 IO - CPU priority 較高 (因為 CPU 使用量較少) - CPU bound - 大多是時間在使用 CPU - CPU priority 較低 - ex. 轉檔 / 科學計算 ### Process 的運作 - Creation - 父程序 create 子程序 - 最終會形成樹狀結構 - 資源分配 - 父子分享所有資源 - 子使用父資源的 subset - 不分享資源 <- 現行做法 - 執行 - 同時執行 - 父等待子結束後才繼續執行 - process creation - address space - 子複製父的 (duplicate) - 然後子程序 load 進剛剛複製的 resource - 把父的 data copy 來 - ex. - fork() - exec() - ![](https://i.imgur.com/5jKqbZq.png =600x) - Termination - C compiler 會在 `main() {}` 最後 "}" 自行插入 `exit();` - 要求 OS 刪掉它 (exit) - 清 memory (de-allocated) - return exit value 給 parent (parent 利用 wait 收到) - synchronous termination (wait) - parent 主動刪除 child - kill - asynchronous termination (signal handling) - 如果 parent 比 child 早結束 - child 會變成孤兒 (orphan process) - 會被 grand-parent 接管 - 通常會被 init / systemd 接管 - init / systemd 實作上會再 kill 掉 orphan - Orphan & Zombie - orphan - parent 提前結束,child 還沒死亡 - orphan 是短暫狀態,會很快被 grandparent 接管 - zombie - parent 沒有收回回傳值 (parent 還沒死亡) - retern value 會卡在 process table (memory) 中,造成不必要的空間浪費 - 實作方法: fork 出 child 後很快 exit,而 parent 沒有 wait,同時讓 parent 活很久 - fork / vfork / clone - [參考](https://blog.xuite.net/ian11832/blogg/23967641-fork%28%29%E3%80%81vfork%28%29%E3%80%81clone%28%29%E7%B3%BB%E7%B5%B1%E5%91%BC%E5%8F%AB%E5%B7%AE%E7%95%B0) - fork: 完全複製出記憶體資料,記憶體位置不同,連 PC 都不一樣的 process - vfork: 子程序完全跑在父程序的 memory 上,父會 blocking 直到子跑完 - clone: 有條件的 clone 出來 ### Inter-Process communication (IPC) ![](https://i.imgur.com/Hd2qcdr.png =400x) - message passing - 有同步效果,可以協調兩端 speed (一端需要等待另外一端塞入資料後才能運行) - 花時間 copy / sys call - IPC-Message passing - pipe() - 接收者應該關掉 output side,利用 input side 接收 - 傳送者應該關掉 input side,利用 output side 傳送 - signal - sync. - ex. /0, overflow - SIGSEGV, SIGFPE - asyn. - ex. kill - SIGKILL, SIGSTOP, SIGCHLD (child 用來送給 parent) - signal handler - default handler: C compiler 幫加了 - 對象是 process - shared memory - 適合交換大量資料 - 需要傳送 signal 才能讓對面知道已經寫完了,可以讀取了 - IPC-Shared memory - shmget(): create - shmat(): attach - shmdt: detach - shmctl: control (通常是用來 delete) - Producer-Consumer Problem - Producer: 提供者,放入 shm 的人 - Consumer: 消耗者,提出 shm 的人 - 用 shm 來同步 prod / cons - 問題: buffer size 是有限的,如何確保得知 buffer 已滿 / 已空 - bounded buffer (環狀設計) - ![](https://i.imgur.com/floXYqB.png =500x) - 問題二: 如何確定 full / empty? - 如果用 counter 來處理,會有 race condition - in = out: 空 - in = (out + 1) % n: 滿 - 以上實做可能會出現 busy-waiting 問題 ## Ch4. Multithreaded ### Overview ![](https://i.imgur.com/yF7iEhh.png) - thread 的 global value (text, data) 共享,local value (stack, heap) 是獨立的 - thread 好處 - 允許在其他 UI 執行時這個 UI input - 資源共享 (share code) (multiprocess 會 copy 一份) - 節能 (thread 比 process 輕量) - 如果有 multi-core,有機會拿來提升效能 - 就算只有 single-core,有時候 multithread 可以幫助寫 code 時的邏輯 - ![](https://i.imgur.com/fFMCZIk.png =500x) - thread 有自己的 - stack pointer - register - shceduling properties - etc. - user thread / kernel thread - user thread 和 kernel thread 的 mapping 方法不再 spec. 上 ### MultiThreading models thread 是否可以被 kernel 看到? Kernel 看到的 thread 數量不必然等於 user space 上的 thread 數量 ![](https://i.imgur.com/SKMkWeY.png =400x) - 主要的幾個 thread libraries - Pthreads (POSIX 中,UNIX 家族的 sys call api) - spec. 上沒有決定如何實作 - 1-1, M-1, M-M - Win32 threads - Java threads - Many-to-One - kernel 看不到 user thread => user thread 會自己 scheduling (timesharing) => 沒有真的平行的效果 - thread 內部自己輪流 - 若其中一個 thread 執行到 blocking code,整個 process 的 thread 都會卡死 (process 看起來還是只有一個) - ex. GNU portable threads (pthread) - ![](https://i.imgur.com/CK3jAEM.png =200x) - One-to-One - 每一 user thread map 到 每一 kernel thread - ![](https://i.imgur.com/r8joZu3.png =300x) - Many-to-Many - 一個 thread 不會 block 到另外一個 thread - OS 只需要製造出足夠的 kernel thread (比 1-1 有效率) - ![](https://i.imgur.com/xR9GgBs.png =300x) - Two-level model - 跟 M:M 很像,但是可以同時多種 model - ![](https://i.imgur.com/ac0kTAb.png =200x) - Light-Weight Processes (LWP) - optional - 像是虛擬化的 processors - ![](https://i.imgur.com/WTfz29E.png =200x) ### Thread libraries - Pthread - POSIX - 只有 spec. 沒有如何時做 - 大概有三種實作: - GNU portable thread - Linux Pthread - Mac OSX Pthread - Win32 thread ### Issue - fork / exec - fork 會 fork 單一 thread 還是所有的 thread 都會一同 fork? - spec. 沒定義 - exec? - 同樣 spec. 沒定義 - Signal Handling - 如果有一個 thread 觸發 signal,會由誰來接收 - Synchronous signal (自己觸發的 signal) - 會交由觸發的 thread 接收 signal - ex. 錯誤存取 - Asynchronous signal (外部觸發) - 通常交由第一個沒有被 block 的 thread 處理 - ex. 程序終止 - Thread Pools - 製造一個 pools 的 thread 等待使用 - 好處 - 比要的時候才製造快 - 允許應用程序中的 thread 數綁定到池的大小 - 類似於多 M:M model 的概念 ## Ch5. CPU Scheduling [Amdahl's law](https://en.wikipedia.org/wiki/Amdahl%27s_law): 平行程式的效能提升一定不是線性的 ### Basic Concept - 何謂 CPU utilization - CPU-IO burst cycle - CPU burst 分配 - CPU Scheduler (short-term scheduler) - 從 ready queue 選出一個 process 來跑 - 發生時機 - from Running to waiting -> 自己願意把 CPU 放出來 - from running to ready -> time slice 用完 - from waiting to ready -> 出現 priority 較高的 ready process - terminates -> 結束 - 上面 2 跟 3 都是需要 preemptive(搶佔) 的 - 種類 - cooperative scheduling (合作型) - 不需要而外 HW (ex. timer) 來處理 - process 主動釋放 CPU - `sleep(0)` or `vield()` -> 都是釋放 CPU 的 sys call - blocking call 也可以造成 context switch - 如果 ill-behaved(ex. 進入無窮迴圈) process 可以造成系統其他 process 永遠搶不到 CPU - preemptive scheduling - 更高的響應 - 更高的 overheads - 需要處理 [race conditions](https://zh.wikipedia.org/wiki/%E7%AB%B6%E7%88%AD%E5%8D%B1%E5%AE%B3) - dispatcher (調度員) - 處理 CPU 的 process selected (short-term) - dispatch latency: dispatcher 在停止一個 process,開啟另外一個 process 間,需要花費的時間 ### Scheduling Criteria (調度標準) - criteria - CPU utilization(使用率): 越高越好 - Throughput(單位時間內完成的 process 數量): 越高越好 - turnaround time(完成一個 process 所需要的總時間): 越低越好 - waiting time(一個 process 完成前,待在 ready queue 的時間): 越低越好 - response time(arrive 到產生第一個 response 所經過的平均時間): 沒有很正式的定義 - waiting + bursting = turnaround ### Scheduling Algorithms - FCFS - First Come First Served - non-preemptible - 不搶占,但也不會讓 CPU 進入 IDLE - 不會 starvation - IO-bound 的 process 可能因為高 waiting time 而很晚才進入 IO - 公平、CPU utilization 高、throughput 低 - SJF - Shortest Job First - 兩種 - non-preemptive - preemptive: 新的 process 進 ready queue 時,都檢查一下現在誰是 shortest job - 只看平均 waiting SJF 一定是最短的 - 可能會有 starvation - 不公平 - 如何預測下一個 CPU burst time - 幾乎不可能 - 利用簡單線性方程式 $\tau_{n+1}=\alpha t_n +(1-\alpha)\tau_n$ - $0 \leq \alpha \leq 1$ (係數) - $\tau_n$ 第 n 個 process 的預測 burst time - $t_n$ 第 n 個 process 的實際 burst time - 試想 - $\alpha = 0 \equiv \tau_{n+1}=\tau_n$: 歷史真實記錄無效 - $\alpha = 1 \equiv \tau_{n+1}=t_n$: 最近一個 burst time 完全影響下一次的預測 - 展開原式,會發現越接近最近的 burst time,越影響預測 - Priority Scheduling - ex. SJF: 越短的 job priority 越高 - 分 preemptive 與 non-preemptive - 可能會 starvation - 解法: aging (會根據時間改變 priority) - Round Robin (RR) - 單位 CPU 的排程 - time quantum (time slice),超過就被搶占 / 進入 ready queue - RR 的 ready queue 適用 FCFS 的 - 當有 n 個 process 在 ready queue,可以預測至少 (n-1) * q 的 time unit 後可以輪到 (q 是 time quantum) - 如果 q 小,call interrupt 的 overhead 就會很大 => 不划算 - 不會 starvation - MultiLevel Queue - ready queue 被分為多種類 - ex. - Foreground - RR - Background - FCFS - process 會根據性質進入不同的 queue - Feedback Queue - process 可以在不同的 queue 間移動 (aging 可以利用這個性質實做) - 前面的 queue 拿完,才進後面的 queue - upgrade / demote - Ex. - Q0 - RR 8 ms - Q1 - RR 16 ms - Q2 - FCFS - schedule: 新的 job 進入 Q0,拿到 CPU time 後開始執行,如果在時限內完成,則結束,如果沒有,會被移動到 Q1。進入 Q1 後同理 - 通常最後會造成 IO-bound 被推到前面(這種 process 常是跟 user 互動的),CPU bound 被推到後面 - 公平,不會 starvation - ![](https://i.imgur.com/qODWmoO.png =400x) ### Multiple Processor Scheduling - 種類 - SMP (Symmetric MultiProcessing) - 對稱式架構,每顆 CPU 同樣重要 - 共用 main memory - 透過 bus 溝通,要設計溝通方法 - 每顆 CPU 自己處理自己的 scheduling - 可以共用 ready queue,也可以有自己的 ready queue - Process 數量小時效能好,架構簡單,擴展性差,cache 如何設計,race condition - ![](https://i.imgur.com/Rmeac6F.png =200x) - NUMA (Non-Uniform Memory Access) - Asymmetric multiprocessing - 只有一個 processor 訪問系統數據結構,減少了 data sharing 的需要 - master - slave 架構 - 擴展性更大 - ![](https://i.imgur.com/Y49go5P.png =300x) - 常見建法: [超立方(hypercube)](https://en.wikipedia.org/wiki/Hypercube): 保證點與點間最長距離 log(n) - Multiple processor scheduling - processor affinity(親和力) - process migration(從一顆 CPU 換到另外一顆 CPU) 的 cost 很高,有時候把 process stick 在同一個 processor 反而比較好 - soft affinity / hard affinity - load balancing - push migration: 將 process 從高載的 CPU 推到 低載的 CPU 的 ready queue - pull migration: 將 waiting process 拉進低載的 CPU 的 ready queue - Linux: 每 200ms 跑一次 push migration / 每次有 empty queue 跑一次 pull migration - process migration 因為 LB 而常用,因為 cache 而少用 (互相衝突) - multicore vs multithreading - multiple processor cores - 在同一個 chip 上 - 快速溝通 / 減少功耗 / cache sharing - multiple hardware threads (per core) - Takes advantage of memory stall to make progress on another thread while memory retrieve happens - A thread here is hardware-oriented, different from “threads” in Chapter 4 - A thread corresponds to a logical processor, emulated by an independent set of registers - 當有多個 thread 時,可以交錯 CPU cycle 與 memory cycle - ![](https://i.imgur.com/KtDO2C2.png =500x) - 個別 register,共用 ALU - 因為 instruction set 有相依性,所以如果邏輯上有多個 CPU,可以交錯執行而減少 Idle time - ![](https://i.imgur.com/t3PgEHj.png =500x) ### Real-Time Scheduling 限制 waiting time 不能超過 n “A real-time system is a system whose correctness includes its response time as well as its functional correctness.” -- IEEE - 兩種類 - soft real-time systems - 不保證何時安排 critical real-time process - ex. packet 要在 streaming buffer 用完前送到並重組 (reassamble) - hard real-time systems - 要在 deadline 前執行完畢 - ex. 飛機航空系統 (控制) - Priority-based Scheduling - 需要有 preemptive 與 priority based scheduling - 但只保證 soft-realtime - periodic process: process 需要 CPU 以恆定間隔進行 - processing time: t, deadline d, period p - $0 \leq t \leq d \leq p$ - ![](https://i.imgur.com/tqZD2DG.png =500x) - Rate Montonic Scheduling (RM Scheduling) - rate(較短的 period) 較高的 process 有較高的 priority - ex. P1 (t=20, p=50), P2 (t=35, p=100), P1 較高 priority - ![](https://i.imgur.com/x9R7BL8.png) - 會出現 missed deadlines - Earliest Deadline First Scheduling (EDF) - CPU 在任何時期都該先做 deadline 較進的 process - ![](https://i.imgur.com/zEe5B3M.png) ### Thread Scheduling - Local Scheduling - thread library 決定哪一個要放入 LWP - Process Contention Scope (PCS) - Global Scheduling - Kernel 決定下一個 run 的 kernel thread - System Contention Scope (SCS) - ![](https://i.imgur.com/NMcqFnp.png =400x) ### OS example - Solaris - RR - 60 條 RR queue - 提早交出 CPU 的 priority 提前 - time slice 用完的 priority 退後 - Windows - 不重要 - Linux - Completely Fair Scheduler (CFS) - virtual runtime - 每個 process 有自己的 runtime - 每使用 n 個 CPU 時間,runtime 就 +n (用這個 n 來控制成長速度(priority 的一種)) - 每次從 RBTree (將 process 以 runtime 建立 RBTree) 中拿出 vRT 小的 process 來執行 - 利用 vRT 成長速率不同,控制 process 使用真的 CPU Time 的長度 - vRT slow: RT 成長慢 -> 較常使用 CPU - vRT fast: RT 成長快 -> RT 一上升,就無法使用 CPU Time - nice value - -20 ~ 19 (high ~ low priority) - 小 nice 值會讓 vRT 成長慢,可得到更多 CPU time - ![](https://i.imgur.com/pLlwF9I.png =500x) ## Ch6. Synchronization 主要問題: 某個操作是由很多小操作組成,而多個小操作不能保證連續過程中不被搶占 ex. Producer-Consumer Problem 利用 counter 來操作 **Race Condition** ### Critical-Section Problem - 正在操作被共用的東西時,需要連續而不會被搶占(interrupt)的操作 - 解法三要素 - Mutual Exclusion: 排他性,不可被搶占 - Progress: 如果 Pj 想使用 resource 而目前沒有 Process 相要使用此 resource,Pj 應該要能夠使用此 resource - Bounded Waiting: 因為 critical section 而進入 waiting 的時間要是可以預測的 (ex. Pj 在 waiting 時,因為 priority 低而永遠進不去) ### Hardware-based approach - synchronization hardware - 需要有能停止 context switch (interrupt) 的 hardware - Interrupt disabling - 設計簡單,小系統上好用 - 問題 1. 如果 multiprocessor 無效 2. privilege instruction 無法在 user mode 使用 3. 程式寫太差了話,造成 interrupt leg 太久(interrupt disable 時),signal 送不進來 - Atomic Instruction - Atomic = non-interruptable - spin locks - Test and set or swap - uniprocessor 與 multiprocessor 都可行 - 透過 Atomic Instruction 幫忙,此時測試並設定 memory 中的 value - 透過 Atomic Instruction 幫忙,此時 swap value - ... ## Ch.7 Deadlock 討論 deadlock 需要一些預設的環境 ### System Model: - 資源: CPU, memory, ... (R1, R2, ...) - 權重: 對每個 R1 有 W1 權重 - 資源效用: 1. request 2. use 3. release - Deadlock 條件(需同時發生): - Mutual execlusion: 一個資源一次只能讓一個 process 用 - Hold and wait: process 同時 拿到一些資源,也等待一些資源 - No preemption: 無法強佔 (如果可以,則可以用搶佔的方式把所有資源拿來跑,跑完還回去繼續用) - Circular wait: 環狀等待 - 將條件用 Graph 表示 - $P = {P_1, P_2, ...}$ process 用 P set 表示 - $R = {R_1, R_2, ...}$ Resourse 用 R set 表示 - Request Edge: Pi -> Rj Pi 需要 Rj 資源 - Assignment Edge: Rj -> Pi Rj 資源給予 Pi 使用 - ex. - ![](https://i.imgur.com/lsCwSye.png =200x) ### Deadlock handling detection or prevention or avoidance (偵測 與 避免) #### Prevention 只要 deadlock 四條件其中一個保證不成立就好 - Mutual Exclusion - 只要是 serially reusable resources 就一定是 mutual exclusion => 無法在這點上避免 deadlock - Hold and Wait - 可以嘗試保證**在 requesting 資源時,沒有 holding 其他資源** - 資源全有全無 - Low concurrency among processes due to long critical sections - 用一個長期執行(long critical sections)的 process 佔用資源,可以在執行期間降低 concurrency(並發性) (執行完就不知道了...) - 缺點:平行度下降 - No Preemption - 可以用 preemption 的機制把被別人 holding 的資源 搶走 - victim (被搶的 process) 要在資源回來時 restart - 需要有 checkpoint 的機制 (reg copy to memory, ...) - Circular Wait - 把 request / assig 變成 DAG (有向無環圖) - 建立一個 total order 或 partial order,只能增序或降序要求資源 #### Avoidence 基於 cycle detection,在給予資源時,先做檢查 - Graph - Claim edge: May use a resource at some time - Request Edge: Requesting a resource - Assignment Edge: holding a resource - 資源可能會在一段時間被 claim (但不一定會被用 hold) (ex. memory allocate 會先要求大一些空間) - 1-Instance Resources (每次更改時,檢查是否有環) 1. 確認所有 claim edges (預測) 2. 當 process 真的要求時,將 claim 改成 request edge 3. 當 resource 可用時,將 request 改成 assignment edge 並重新檢查是否有環 4. 如果檢查發現有環,將 request 改回 assignment edge => 沒有環 - 另外一種方法: - 用 highest level lock 來鎖著 cycle - N-Instance Resources - graph-based approach - safe / unsafe-state method - safe sys: 沒有 deadlock - 給予資源時都要持續保證保持在 safe-state - 需要定義 safe-state - ![](https://i.imgur.com/QQGPBNk.png =200x) - Safe-State - Process 需要 resources 時,系統應該馬上知道給予資源是否會破壞 stafe state - safe sequence 可以維護 safe state - safe sequence 中的 process 可以 request 的資源是**目前可以使用的資源 或 前面的 process 握住的資源** - 如果 request 前面 process 正在使用的資源,當那個 process 結束後,馬上可以給這個 process 使用 ##### Banker's Algorithm 對於 N-Instances,需要預測做大要求資源,等待拿到資源,以及在拿到所有要求資源後,要在時限內環回來 - Data - Available: Avai[j] = k (紀錄 type j 的 Resource 有多少資源可用) - Max: M[i, j] (Pi 最大會要求多少 Resource j) - Allocation: Allo[i, j] (紀錄 Pi 已經佔用了多少 Rj) - Need: N[i, j] (紀錄 Pi 還需要多少 Rj) - Need[i, j] = Max[i, j] - Allo[i, j] - Safety Algo. - Max - Allo = Need (為什麼要用最大需求:如果可以符合最大需求,就一定可以符合比最大需求小的一班需求) - => 算出 Need,排出每次 Available > Need 的序列,並且當次用完後,Need 可被加回 Available - 如果可以找到上述序列,就可以用這個序列保證 saft-state #### Detection Detection & Recovery (週期性檢查) - Single Instance - 維護 wait-for graph - Pi -> Pj: Pi 等待 Pj 用完 Resource (per resource) - 定期檢查 cycle - 拓墣排序 用 $n^2$ 檢查 cycle - Resource-Allocation Graph -> Wait-for Graph - ![](https://i.imgur.com/8GcDeEG.png =300x) - Detection Algo. - 一樣找出 available / allocation / request - 方法: - 看不大懂 @@a - Deadlock detection 保證 safe state,unsafe 不保證 一定會 deadlock - 如果 detect 到 => roll back 一些 process - Recovery - Kill Process - 選擇 order - Preemption - victim selection (minimize cost) - Rollback - 要避免 Starvation (因為用了 preemption) ### Summary - Deadlock => 四條件 (mutual exclusion, hold and wait, non-preemptible, circular wait) - 四條件擇一不成立 => 必定無 deadlock - prevention - 擇一取消 - avoidance - 拒絕會產生 DL 的 resource request - 1-instance per resource - DL <-> cycle - safe state <-> no DL - N-instance - DL -> cycle - safe state -> no DL - DL -> unsafe - safety check ## Ch.8 Memory Management ### Address binding 程式必須被帶入 memeory 並載入 processor 才可以變成 程序 如何將 data / instruction 從 disk 帶入 memory - Binding inst. / data to Memory,有三種時間會 bind to mem. - Compile time - static link: compile 時就知道放到 MM 的哪裡 (絕對位置) - 如果位置改變就要重新 compile - Load time - 如果不知道執行時的 memory address,compiler 就必須寫入記憶體相對位置,在 load program 時才決定位置 - relocatable instructions - non-relocatable instructions - ![](https://i.imgur.com/UBAD1ql.png =500x) - ![](https://i.imgur.com/EsA4q1p.png =500x) - Execution time - dynamic link - .dll / .so 檔 - 當程式用到時才會載入,每次載入時 address 都會不同,可以多個 process 共用 ex. glibc - address table / GOT 處理 dynamic linking address 位址 - 安全 - 不同種類的 memory management - Logical address: CPU 產出的,也叫做 virtual memory - Physical address: memory unit 看到的 - User program 永遠只看得到 logical address - 需要 hardware 幫忙轉 logical 成 physical - ![](https://i.imgur.com/j7ktwT5.png) - MMU (Memory Management Unit) - CPU 中將 logical 轉為 physical address - Paging - Address mapping - Virtual memory - Segmentation - Memory protection ### Contiguous Memory Allocation ![](https://i.imgur.com/tVt50TS.png =400x) - 連續分派 - MM 通常會被分成兩部分 - OS 保留,low memory 上,包含 interrupt vector - User processes - Single-partition allocation - Relocation 可以讓 user process 互相隔離,並且益於更改環境(系統)與資料 - Limit register 紀載 logical address range 並限制使用大小 - ![](https://i.imgur.com/0iMUbgT.png =400x) - Memory Allocation - 給 process 的記憶體空間一定要連續 - 然,連續給出 process 再隨 process 結束後收回,會出現 free memory 片段(不連續)問題 - 如何安全且有效率地給出 free holes - First fit - 效率 - Best fit: 給出最小符合 - 盡量保留最大連續空間,但是剩餘的小空間會**非常**難使用 - Worst-fit: 給出最大符合 - 與上相反,通常會留下很多差不多大小的洞 - 速度與使用效率都是最差的 - Buddy System: 都已 $2^n$ 給記憶體 (類似切網段) - 速度快,破碎化不一定多 - [Fragmentation](https://zh.wikipedia.org/wiki/%E7%A2%8E%E7%89%87%E5%8C%96) - External Fragmentation - 切割零碎,雖然剩下的加總記憶體空間夠程序使用,但連續空間不夠程序使用,使得程序無法執行 - Internal Fragmentation - 作業系統配置給 process 的 memory 空間大於 process 真正所需的空間,這些多出來的空間該 process 用不到,而且也沒辦法供其他 process 使用,形成浪費。(配合 paging / buddy system) ### Paging 當出現 Fragmentation 問題時,是否可以將零碎的空間收回,再統一釋放使用 需要所有的 program relocate => OS 降速 => 是否可以 邏輯上連續,而實際上不一定連續呢? - Page - 將物理 mem. 切割成塊(frame),通常 4k - 將邏輯 mem. 切割成塊(page),與 frame 同大 - 再需要用到 mem. 時,建立 page table 指派到沒用的 frame,並且將這些 frame 標記為正在使用 - ![](https://i.imgur.com/zeR8GEA.png =500x) - Implementation of Page Table - 每個 process 都有自己的 Page Table - Page-table base register (PTBR) 指向 page table - Page-table length register (PRLR) 代表 page table size - 存在 Main memory - 需要兩次的 mem access 才能執行/存取,一次是查找 page table,一次是載入 data/instruction - 兩次記憶體查找問題可以用特殊硬體快速解決 associative memory / translation look-aside buffers (TLBs) - TLB 是 page table 的 catch - ![](https://i.imgur.com/vqxhmGZ.png =450x) <p style="color: red">這裡怎麼計算是重點,求有緣人補充 XD</p> - Effective Access Time - $\varepsilon$: 查找 TLB 時間 - $\alpha$: Hit ratio - $T$: memory access time - $EAT = (1T+ \varepsilon) \cdotp \alpha + (2T+\varepsilon)(1-\alpha) = 2 + \varepsilon - \alpha$ - 1 是 TLB hit 只需要載入 data/instruction 一次記憶體存取,2 是 TLB miss 需要查找 Pabe table + 載入 - $\varepsilon$ 很小 ### Structure of the Page Table #### Hierarchical Paging - 每個 process 一個 PT,且 PT 大且連續 是不方便且無效率的 - 既然 PT 也是在 mem. 中的,是否也可以被切片 - fragmented (不用連續) - allocated on demand (省空間) - two-levle PT - ![](https://i.imgur.com/RyBvv2u.png =300x) - 原來 20 個 entry => 10\*10 = 100 個 entry => 邏輯空間大,若 TLB miss 高,會消耗很多效率 - 應該是 logi(page) -> phy(outer page table) -> phy(page of page table) -> phy(frame),不然會出現地回查找問題 #### Hashed Page Tables 記憶體稀疏且邏輯位址空間大時,適合用這種 - 適合真正使用的記憶體遠小於邏輯記憶體空間 (稀疏) #### Inverted Page Table - 邏輯空間的總大小會隨的 process 數量上升而變大 (logi mem. 是 per-process 的),但 phy. mem. 不會跟著變大 - inverted page table 的大小只跟 phy mem 有關,跟 log mem. 無關 - 全部 process 只有一個 page table - PT 內部存的是 pid 與 page number - search 到對的 pid 與 page number 時,search index 就是 frame num. ![](https://i.imgur.com/rDcyqpq.png =400x) ### Segmentation 從 per-process 的角度看 memroy,不用管 mem.-management 等 phy. 的東西 ![](https://i.imgur.com/dlms0Cb.png =200x) - Hardware - Logical address: <segment-number, offset> - Segment table (map phy. addr.) - base: 從哪裡 - limit: 多長 - Segment-table base register (STBR) - Segment-table length register (STLR) - 也有類似 PT 的東西 - ![](https://i.imgur.com/8CdQ6HG.png) - Segment Protection - 一些安全性規範,ex. 某些地方可執行不可寫入 ## Ch.9 Virtual-Memory ### Demand Paging - Memory Protection - protection bit - valid-invalid - valid: 存在 process 的 local address space,是 legal page - invalid: 不在 process 的 local address space - invalid page 可能是 illegal 或 valid 但還沒被 referenced ![](https://i.imgur.com/UY6Mq7d.png =300x) - Virtual Memory 有多種理由用 VM - 只有 program 中的一部分需要在 memory 中 (其他可以執行到在載入等等) - VM 可以比 phy. 開的還要大 - 更加高效 (process 開始時,不用真的買上把 mem. 開起來) - 可以有 share memory ![](https://i.imgur.com/gvSExjX.png =300x) - VM 多用 demanded paging 實作 - 當 VM 摸到 invalide 的 main mem. 時(page fault),OS 再去要新的 mem. (ex. swap in) - Demand Paging - VM 可以比 phy. mem. 還大 - 只有在需要時,才把 page 拉近 memory (從 disk) - 減少 IO - 增加 process 數量 (減少 mem 需求) - 回應速度加快 (跟加速 process 開啟時間原因相等) - ![](https://i.imgur.com/cE932mK.png =450x) - Performance of DP - Page Fault Rate: p - $EAT = (1-p) * mem.access + p * (page_fault_overhead + swap_out + swap_in + restart_overhead)$ - TLB - hit - 絕對不會 page fault - miss - not page fault - 去 PT 把 cache 抓回 TLB - page fault - 去 disk 抓進 PT 再抓進 TLB ### Page Replacement 避免 over-allocation,需要有 page 回收機制 回收機制在 logical 與 physical 是分開做互不影響的 - Basic Replacement 1. 找 frame - 如果有 free frame => 直接用 - 如果沒 free frame => 複寫一個 victim frame 2. 讀 data 進 frame 3. 更新 PT 跟 frame table 4. restart process - Page Repolacement 如何選出 victim frame - 有些 data 不用寫回,可以省一次 IO - 用 dirty bit 紀錄是否需要寫回 - ![](https://i.imgur.com/sNBqP0l.png =300x) - ![](https://i.imgur.com/OMlSKCl.png =300x) - Replacement 方法 - FIFO (first in first out) - OPT (Optimal page replacement) - 誰的下一次 reference 最遠選他 - but process 無法預測 - 當作效能分析的 upper bound - LRU (least-recently used) - 上次用裡現在最久的 - Belady’s anomaly 當 Process 分配到較多的 Frame 數量,有時其 Page Fault Ratio 卻不降反升 - LRU 相似算法 - Reference bit - 當這個 page 有被 reference 時,將 bit 設為一 - 優先更新 RB = 0 的 - 無法得知 RB = 1 的人誰先誰後 - Second chance - 多一個 clock 固定清掉 RB - ![](https://i.imgur.com/q1B5TVp.png =450x) - Enhanced Second-Chance Algo. - 再多一個 dirty bit - dirty bit 需要 mem IO 兩次,會比沒有 dirty bit 的人更耗時 - (ref, dirty) victim 選擇順序 1. (0, 0) 2. (0, 1) 3. (1, 0) 4. (1, 1) - Counting - LFU (Frequency) - 更新最小 count 的 - 用 counter 的半衰期(left shift) 解決時間影響 - MFU - 更新最大 count 的 - 因為覺得最少使用的應該是剛剛進來的,不久之後就要使用了 ### Thrashing Thrashing == busy swapping in and out Page size 不夠導致高 page fault rate,造成 - 低 CPU 使用率 - OS 可能會以為需要一狀況提高 mutiprogramming 的維度 - 更多 process 加入 ### Performance 再背景定期做 swapout 確保 free frame 夠多 & 背景執行不影響效能 - Pre-paging - 避免 process 剛起來時有大量的 page fault,預先作 swap in - 但是可能載入大量錯誤 / 不需要的 data - TLB Reach - TLB Reach = (TLB size) * (Page size) - 有這麼多的 mem data size 是可以直接查找 TLB 就找到的 - 理想上 working set 的 data 都要可以進 TLB => 高效 - 也許會想要提高 TLB size,但是 TLB 需要大面積電路且功耗高 - 兩方法: - 增加 page size - 可能會產生高 IO、page fault,載入一整條 page 都不用 - 提供 multiple page size - 比較常用的方法 - Page Size Tradeoff - Large - page table 相對小 - 大 TLB reach - 高 page fault - Small - 大 page table - 小 TLB reach - 低 page fault - 對 Page size - 希望 大 page siez => 小 page table - 小 page table 再 page search 時可以減少第一次 memory access time - 對 IO - 大 page size - 序列畫 IO 一次近來 - 對 locality - 小 page size 可以比較精確的抓到要的值 ### Share Page 兩個 process 各自維護的 page 共用同一個 frame - way - 程式共用 .dll / .so - lib 動態載入 - share memory - ![](https://i.imgur.com/h2NTzdg.png) ### Copy on Write (COW) - 常見於 fork - 當 parent fork 出 child 時,理論上會式兩份 mem.,可是為了加速,可能會用 share frame 的方式,並設定 read only - 如果 write 時會需要 trap,然後才 copy 出自己這份 - 只有再要 write 時,會再把 frame copy 一份並更新 page table ### Swap & Memory-Mapped File - Swap-space (VM mapping 到 disk 上) - Linux: Swap partition - windows: pagefile.sys - swap-map: 追蹤 swap out 與 位置 - ![](https://i.imgur.com/OqyBOln.png) - Memory Mapping Files - 正常 file RW 需要 disk IO (system call) - 如果把 file 當作 swap space,就可以用記憶體方式操作 - 好處 - 方便好用 (ex. linux shared memory) - 不需要 user-kernel mode 轉換 - 可以 多 process 共用 - ![](https://i.imgur.com/Kv4Qlt1.png =400x) ### Swapping - Blocking store - 非揮發性儲存 - Swap out, in - 有 priority 決定誰出誰進 - ![](https://i.imgur.com/5Fy1qJq.png =300x)