零拷贝并不是不需要拷贝,而是减少不必要的拷贝次数。
通常我们需要访问硬盘数据的时候,用户进程需要借助内核来访问硬盘的数据;用户通过调用系统方法,如 read()、write()等方法通知内核,让内核做相应的事情。
read();
复制代码
传统读取数据的流程:
在没有 DMA 之前的拷贝流程如上图所示:
以上流程中,涉及到数据的拷贝都需要 CPU 来完成,CPU 是非常珍贵的资源,CPU 在拷贝数据的时候,无法做其他的事情,如果传输的数据非常大,那么 CPU 一直在拷贝数据,无法执行其他工作,代价非常大。
本质上,DMA 技术就是计算机主板上一块独立的芯片,当计算机需要在内存和 I/O 设备进行数据传输的时候,不再需要 CPU 来执行耗时的 IO 操作,而是通过 DMA 控制器来完成,流程如下。
上图可知,数据拷贝由 DMA 完成,CPU 不需要在执行一些耗时的 IO 操作。
下图可以更形象的表达文件传输的过程:
步骤说明如下:
以上传统的 IO 数据拷贝在性能上有很大的提升空间,
由上图看出,在文件传输的案例中,我们将数据拷贝到用户数据缓冲区,用户进程没有经过任何数据处理,将文件直接发送出去。因此,这一个步骤是多余的,可以省略。
零拷贝的实现主要是针对上下文切换和拷贝的次数进行优化,通过减少上下文切换和减少数据拷贝的次数来达到优化的目的。
mmap 全称 Memory Mapped Files,是一种内存文件映射的方法,将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中的一段虚拟地址的一一映射关系,映射关系生成之后,用户进程可以通过指针操作内存中的文件数据,系统会自动将操作后的数据写入到磁盘中,而不需要调用 read(),write()等系统调用来操作数据。
使用 mmap()函数替换 read()函数,mmap 将内核缓冲区中的数据映射到用户空间,用户空间与内核之间就不需要进行数据的拷贝,他们可以进行数据共享。
如图可以看出,数据不再拷贝到用户缓冲区
mmap 减少了一次数据的拷贝,性能有所提升,但还是存在 4 次用户态和内核态的切换,并不是最理想的零拷贝。
用户进程没有权限直接操作磁盘的数据,内核拥有上帝的权限,所以用户进程可以通过调用系统函数(如 read,wirte)将任务交给内核来完成。
一次系统调用会发生两次上下文切换,先从用户态切换到内核态执行任务,任务执行完成后,从内核态切换到用户态,用户进程继续执行逻辑。
上下文的切回需要耗费时间,每次上下文切换耗费几纳秒到几微妙,看起来时间很短,但在并发下会成倍放大。
因此,我们需要减少上下文切换的次数,要减少上下文切换的次数,就需要减少系统函数调用的次数。
Linux 2.1 版本后提供了一个专门发送文件的系统调用函数 sendfile(),函数如下:
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
复制代码
参数说明:
out_fd : 目的地端的文件描述符
in_fd:源端的文件描述符
offset: 源端的偏移量
count:复制的长度
返回实际复制数据的长度
sendfile 函数用于代替 read 和 write 两个函数,这样就可以减少一次系统调用,减少两次上下文切换的开销。
$ ethtool -k eth0 | grep scatter-gatherscatter-gather: on
复制代码
以上过程只涉及到一次系统函数调用,2 次上下文切换,2 次 DMA 数据拷贝,不需要 CPU 拷贝数据,实现了真正的零拷贝。
PageCache 为磁盘的高速缓冲区,由于在磁盘中找数据是非常耗时的操作,所以将磁盘中的部分数据缓存到 PageCache 中,将读写磁盘的操作转换到内存中,提高读写的效率。
PageCache 内存空间相比于磁盘来说小很多,所以我们不可能把所有的数据放到磁盘中,那么我们需要将什么数据读取到内存中,读取多大?
PageCache 使用了预读功能,假如我们需要读取 32kb 的数据,但是加载到内存中的数据不只是 32kb,它会以页为单位(每页 64kb)来读取数据,所以不仅会读取 0-32kb 的数据,还会读取 32-64kb 的数据,这样 32-64kb 部分的数据读取的代价非常小,如果在内存淘汰前被进程使用到,收益非常大。
所以 PageCache 有两个主要的好处:
说白了 PageCache 的诞生就是为了提高磁盘的读写性能。
答:先说答案:异步 IO + 直接 IO 这个情况我们应该想办法绕过 PageCache,大文件不应该使用 PageCache 直接 IO 会直接绕过 PageCacheIO 的读取是阻塞的,可以考虑使用异步 IO 去代替
欢迎大家讨论。
文/木匠
关注得物技术,携手走向技术的云端
领取专属 10元无门槛券
私享最新 技术干货