假設一個process需要對storage子系統讀寫一個大檔案。請用三個值中的一個回答下列五個小題:(A) – less than,(B) – greater than,(C) – similar to。
假設I/O model採用blocking I/O,要儲存的檔案非常大,且system load造成的延遲可以忽略。檔案系統的資料區塊為4K-byte。
下表顯示process的設定與待回答的小題。第一欄定義buffering model,第二欄定義該buffering model的參數,第三欄顯示用來儲存資料所使用的函式呼叫。表格第一列代表baseline,也就是unbuffered I/O、4K buffer size、且沒有disk synchronization的組合,後續小題都要跟這個baseline比較。
| Setting(Buffering model) | Setting(參數) | 函式呼叫 | 待回答小題 |
|---|---|---|---|
| Unbuffered IO | Buf Size 4KB | write() | (baseline,用來比較) |
| Unbuffered IO | Buf Size 4KB | fsync() after write() | (a) (2 pts) Clock time與baseline相比如何? |
| Unbuffered IO | Buf Size 8KB | fsync() after write() | (b) (2 pts) User CPU time與baseline相比如何? |
| Buffered IO | line-at-a-time | puts() | (c) (2 pts) System CPU time與baseline相比如何? |
| Buffered IO | fully buffer | puts() | (d) (2 pts) User CPU time與baseline相比如何? |
| Buffered IO | fully buffer | puts()+fflush()+fsync() | (e) (2 pts) System CPU time與baseline相比如何? |
參考答案與解析
本題以 APUE(Stevens)的 I/O 效能量測為背景。baseline 是 unbuffered write()、4KB buffer、不做 fsync。
(a) (B) greater than。每次 write() 後呼叫 fsync(),要等資料真正寫到磁碟才返回;baseline 的 write() 只把資料複製進 kernel 的 page cache 就返回,clock time 大幅增加。
(b) (C) similar to。user CPU time 只包含 user space 的迴圈與發出 system call 的少量指令。buffer 從 4KB 加到 8KB,system call 次數減半,但 4KB 時這部分已經趨近於零;檔案系統的 block 是 4KB,buffer 超過 block 大小後幾乎不再有差別。fsync() 的工作在 kernel 內完成,不計入 user CPU time。
(c) (B) greater than。line-at-a-time buffering 每遇到換行就呼叫一次 write(),system call 次數遠多於 baseline 以 4KB 為單位寫入,system CPU time 增加。
(d) (B) greater than。fully buffered 的 puts() 最後同樣以 block 大小呼叫 write(),但每次 puts() 都要在 user space 把資料複製進 stdio 緩衝區、檢查是否要 flush,這些工作都計入 user CPU time,比直接呼叫 write() 的 baseline 多(APUE 的量測中,stdio 版本的 user CPU time 明顯高於 read/write 版本)。
(e) (B) greater than。fflush() 觸發 write(),fsync() 還要在 kernel 內把資料與 metadata 寫回磁碟,system CPU time 比 baseline 高。