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

使用这种kernel buffer
作为中转站的好处:
当要读的数据不大于 kernel buffer的大小时, 该buffer可以作为一个读缓存,来提高读的效率
在写端的时候,可以作为一个异步写
坏处:
当要读写的数据大小超过kernel buffer的大小的时候, 数据各个冗余地方的copy会很低效
2. 优化1
从以上的read-send
过程可以看出, 中间user-buffer
的使用可以避免掉
从下图可以看出进行了3次copy

3. 优化2
从以上过程可以看出 read buffer
到 socket buffer
之前数据的copy也是可以去掉的 (当底层的网卡接口支持gather operations 时)
从下图可以看出进行了2次copy

3. 以上3中方法的比较
方面 | 原来 | opt1 | opt2 |
---|---|---|---|
context switch 的次数 | 4 | 2 | 2 |
数据copy的次数 | 4 | 3 | 2 |
网友评论