- 哪些操作会造成用户态和内核态的切换? 都是从哪里切换到哪里 ?
- 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 |