| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 面试官:linux零拷贝的原理是什么? -> 正文阅读 |
|
[系统运维]面试官:linux零拷贝的原理是什么? |
1.前言 想到这里,我开始慌了,所以今天和大家一起学习个底层技术点-零拷贝Zero-Copy。 Linux系统中一切皆文件,仔细想一下Linux系统的很多活动无外乎读操作和写操作,零拷贝就是为了提高读写性能而出现的。 废话不多说,马上开大车,走起!
上述数据流转只是大框,接下来看看几种模式。 2.1 仅CPU方式 2.2 CPU&DMA方式 直接内存访问(Direct Memory Access),是一种硬件设备绕开CPU独立直接访问内存的机制。所以DMA在一定程度上解放了CPU,把之前CPU的杂活让硬件直接自己做了,提高了CPU效率。 目前支持DMA的硬件包括:网卡、声卡、显卡、磁盘控制器等。 有了DMA的参与之后的流程发生了一些变化: 最主要的变化是,CPU不再和磁盘直接交互,而是DMA和磁盘交互并且将数据从磁盘缓冲区拷贝到内核缓冲区,之后的过程类似。 “【敲黑板】无论从仅CPU方式和DMA&CPU方式,都存在多次冗余数据拷贝和内核态&用户态的切换。 我们继续思考Web服务器读取本地磁盘文件数据再通过网络传输给用户的详细过程。 3.普通模式数据交互 系统调用syscall是应用程序和内核交互的桥梁,每次进行调用/返回就会产生两次切换: 调用syscall 从用户态切换到内核态 来看下完整的数据拷贝过程简图: 读数据过程: 应用程序要读取磁盘数据,调用read()函数从而实现用户态切换内核态,这是第1次状态切换; 应用程序要向网卡写数据,调用write()函数实现用户态切换内核态,这是第1次切换; 读过程涉及2次空间切换、1次DMA拷贝、1次CPU拷贝;
我们需要降低冗余数据拷贝、解放CPU,这也就是零拷贝Zero-Copy技术。 4.2 解决思路 4.2.1 mmap方式 这样就减少了一次用户态和内核态的CPU拷贝,但是在内核空间内仍然有一次CPU拷贝。 mmap对大文件传输有一定优势,但是小文件可能出现碎片,并且在多个进程同时操作文件时可能产生引发coredump的signal。 4.2.2 sendfile方式 sendfile系统调用是在 Linux 内核2.1版本中被引入,它建立了两个文件之间的传输通道。 sendfile方式只使用一个函数就可以完成之前的read+write 和 mmap+write的功能,这样就少了2次状态切换,由于数据不经过用户缓冲区,因此该数据无法被修改。
从图中可以看到,应用程序只需要调用sendfile函数即可完成,只有2次状态切换、1次CPU拷贝、2次DMA拷贝。 但是sendfile在内核缓冲区和socket缓冲区仍然存在一次CPU拷贝,或许这个还可以优化。 4.2.3 sendfile+DMA收集 升级后的sendfile将内核空间缓冲区中对应的数据描述信息(文件描述符、地址偏移量等信息)记录到socket缓冲区中。 DMA控制器根据socket缓冲区中的地址和偏移量将数据从内核缓冲区拷贝到网卡中,从而省去了内核空间中仅剩1次CPU拷贝。 这种方式有2次状态切换、0次CPU拷贝、2次DMA拷贝,但是仍然无法对数据进行修改,并且需要硬件层面DMA的支持,并且sendfile只能将文件数据拷贝到socket描述符上,有一定的局限性。 4.2.4 splice方式 splice 系统调用可以在内核缓冲区和socket缓冲区之间建立管道来传输数据,避免了两者之间的 CPU 拷贝操作。 splice也有一些局限,它的两个文件描述符参数中有一个必须是管道设备。 5.本文小结 零拷贝技术是非常底层且重要的读写优化,对于服务并发能力的提升有很大帮助,就这么多吧,下期再见! 最后 如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 ! PHP学习手册:https://doc.crmeb.com |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 4:42:33- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |