9、零拷贝
9.1、为什么要有DMA技术?
1、在没有 DMA 技术前,I/O 的过程:
- CPU 发出对应的指令给磁盘控制器,然后返回;
- 磁盘控制器收到指令后,于是就开始准备数据,会把数据放⼊到磁盘控制器的内部缓冲区中,然后产⽣⼀个中断;
- CPU 收到中断信号后,停下⼿头的⼯作,接着把磁盘控制器的缓冲区的数据⼀次⼀个字节地读进⾃⼰的寄存器,然后再把寄存器⾥的数据写⼊到内存,⽽在数据传输的期间 CPU 是⽆法执⾏其他任务的。
2、什么是DMA技术?
DMA(Direct Memory Access):直接内存访问,核心是在进行I/O设备和内存的数据传输的时候,数据搬运的工作全部交给DMA控制器,而CPU不再参与任何与数据搬运相关的事情,这样CPU就可以去处理其他事务。
3、有DMA技术后,I/O的过程:
- 用户调用read(),向操作系统发出I/O请求,请求读取数据到自己的内存缓冲区中,进程进入阻塞状态;
- 操作系统接收到I/O请求后,进一步将I/O请求发送DMA,然后CPU执行其他任务
- DMA将I/O请求发送给磁盘;
- 磁盘收到 DMA 的 I/O 请求,把数据从磁盘读取到磁盘控制器的缓冲区中,当磁盘控制器的缓冲区被读满后,向 DMA 发起中断信号,告知⾃⼰缓冲区已满;
- DMA 收到磁盘的信号,将磁盘控制器缓冲区中的数据拷⻉到内核缓冲区中,此时不占⽤ CPU,CPU可以执⾏其他任务;
- 当 DMA 读取了⾜够多的数据,就会发送中断信号给 CPU;
- CPU 收到 DMA 的信号,知道数据已经准备好,于是将数据从内核拷⻉到⽤户空间,系统调⽤返回;
9.2、如何优化文件传输性能?
1、传统的I/O工作方式
传统的I/O工作方式是:数据读取和写入都是从用户空间到内核空间来回复制,而内核空间的数据是通过操作系统层面的I/O接口从磁盘读取或写入。
//两个系统调用函数:
read(file, tmp_buf, len);
write(socket, tmp_buf, len);