- 哪些操作會造成用戶態和內核態的切換? 都是從哪里切換到哪里 ?
- zero-copy 是真正的zero嗎 ?
1. 正常的讀寫數據涉及到的 context switch
system call | from | to | data location |
---|---|---|---|
read |
U |
K |
disk --> kernel address space buffer |
read (第二階段) |
K |
U |
kernel buffer --> user buffer |
send |
U |
K |
user buffer --> kernel buffer |
send (第二階段) |
K |
U |
kernel buffer --> protocol engine |
ps: K
: kernel mode, U
: user mode
從下圖可以看出進行了4次copy
context switch
使用這種kernel buffer
作為中轉站的好處:
當要讀的數據不大于 kernel buffer的大小時, 該buffer可以作為一個讀緩存,來提高讀的效率
在寫端的時候,可以作為一個異步寫
壞處:
當要讀寫的數據大小超過kernel buffer的大小的時候, 數據各個冗余地方的copy會很低效
2. 優化1
從以上的read-send
過程可以看出, 中間user-buffer
的使用可以避免掉
從下圖可以看出進行了3次copy
opt1
3. 優化2
從以上過程可以看出 read buffer
到 socket buffer
之前數據的copy也是可以去掉的 (當底層的網卡接口支持gather operations 時)
從下圖可以看出進行了2次copy
opt2
3. 以上3中方法的比較
方面 | 原來 | opt1 | opt2 |
---|---|---|---|
context switch 的次數 | 4 | 2 | 2 |
數據copy的次數 | 4 | 3 | 2 |