一、DMA(直接内存访问)
1.作用:解决大量数据转移过度消耗CPU资源的问题
2.实现原理:在进行I/O设备和内存的数据传输时,数据搬运到内存的工作全部交给DMA控制器,而CPU不再参加与数据搬运相关的事情。
比如在文件传输:原本CPU负责将磁盘控制器缓冲区的内容搬运到内核缓冲区(PageCache,磁盘高速缓存),现在这个工作交给DMA控制器来完成,CPU负责告诉DMA传什么数据、从哪里传到哪里;将数据从内核拷贝到用户空间
二、零拷贝
1.作用:减少内存拷贝的次数。
以文件传输为例:原本使用read+write,两次系统调用(一次系统调用两次上下文切换,即用户态-内核态-用户态,共四次上下文切换),四次拷贝
数据拷贝过程:磁盘缓冲区-(DMA)内核缓冲区-(CPU)用户缓冲区-(CPU)socket缓冲区-(DMA)网卡缓冲区
2.实现方法
(1)mmap+write(两次系统调用,三次拷贝):调用mmap()系统函数会直接把内核缓冲区的数据映射到用户空间,应用进程和操作系统内核共享这些数据;应用进程再调用write()将内核缓冲区数据拷贝到socket缓冲区里(这个过程发生在内核空间,相当于少了一次从内核空间到用户空间的拷贝操作)
(2)sendfile(一次系统调用,三次拷贝):也是能直接将内核缓冲区数据拷贝到socket缓冲区里,但只需要一次系统调用。
(3)真正的零拷贝技术(一次系统调用,两次拷贝):支持SG-DMA的话,DMA将磁盘数据拷贝到内核缓冲区,再用DMA将数据从内核缓冲区拷贝到网卡缓冲区。“零”指的是没有在内存层面拷贝数据,全程没有CPU只有DMA在搬运数据
3.应用:kafka、Nginx