一、零拷贝技术的三个思路
用户态直接IO,以后再来博客补充
减少数据拷贝次数
写时复制技术,后面看c++的时候将
二、减少数据拷贝次数
首先比较一下几个接口,粗略的
| read+write | mmap+write | sendfile | splice |
上下文切换 | 各两次,共四次 | 各两次,共四次 | 仅本系统调用,两次 | 仅本系统调用,两次 |
CPU拷贝 | 2(内核态和用户态之间) | 1(内核缓冲区和socket缓冲区) | 1 | 0 |
DMA拷贝 | 2 | 2 | 2(从磁盘到内核缓冲区) | 2 |
备注 | 仅使用与从文件拷贝到socket套接字 |
三、粗略讲一下另外俩
1、写时复制指的是当多个进程共享同一块数据时,如果其中一个进程需要对这份数据进行修改,那么就需要将其拷贝到自己的进程地址空间中。这样做并不影响其他进程对这块数据的操作,每个进程要修改的时候才会进行拷贝,所以叫写时拷贝。
这种方法在某种程度上能够降低系统开销,如果某个进程永远不会对所访问的数据进行更改,那么也就永远不需要拷贝。
2、用户态直接 I/O 使得应用进程或运行在用户态(user space)下的库函数直接访问硬件设备,数据直接跨过内核进行传输,内核在数据传输过程除了进行必要的虚拟存储配置工作之外,不参与任何其他工作,这种方式能够直接绕过内核,极大提高了性能。
用户态直接 I/O 只能适用于不需要内核缓冲区处理的应用程序,这些应用程序通常在进程地址空间有自己的数据缓存机制,称为自缓存应用程序,如数据库管理系统就是一个代表。其次,这种零拷贝机制会直接操作磁盘 I/O,由于 CPU 和磁盘 I/O 之间的执行时间差距,会造成大量资源的浪费,解决方案是配合异步 I/O 使用。
ps:
注意,读写优化技术远不止这几种,同时每个接口还有好多变形,详见下面博客,有时间我也整理一个