计算机操作系统学习笔记(11)——零拷贝

简介: 计算机操作系统学习笔记(11)——零拷贝

一、DMAfb19c2eea21e4d49a28fc73210819b24.png

DMA(直接内存存取)

为什么要有 DMA 技术?

没有DMA的时候,IO整个数据的传输过程,都要需要 CPU 亲⾃参与搬运数据的过程,⽽且这个过程,CPU 是不能做其他事情的。


有了DMA技术。在进⾏ I/O 设备和内存的数据传输的时候,数据搬运的⼯作全部交给 DMA 控制器,⽽ CPU 不再参与任何与数据搬运相关的事情,这样 CPU 就可以去处理别的事务。

说白了就是引入了DMA,帮CPU干了一部分工作,这样CPU就可以腾出手干其他事情了


二、传统文件IO

传统文件IO需要用到2个函数:

read(file, tmp_buf, len);
write(socket, tmp_buf, len);

fb19c2eea21e4d49a28fc73210819b24.png

发⽣了 4 次⽤户态与内核态的上下⽂切换, 4 次数据拷⻉(两次DMA 拷⻉,两次 CPU 拷⻉)

传统的IO性能是非常差的,所以,要想提⾼⽂件传输的性能,就需要减少「⽤户态与内核态的上下⽂切换」和「内存拷⻉」的次数。

三、如何实现零拷⻉?

零拷⻉技术实现的⽅式通常有 2 种:

mmap + write

sendfile

mmap + write


我们可以⽤ mmap() 替换 read() 系统调⽤函数。

buf = mmap(file, len);
write(sockfd, buf, len);

仍然需要 4 次上下⽂切换,因为系统调⽤还是 2 次。但是拷贝从4次变成了3次

sendfile

在 Linux 内核版本 2.1 中,提供了⼀个专⻔发送⽂件的系统调⽤函数 sendfile()

它可以替代前⾯的 read() 和 write() 这两个系统调⽤,这样就可以减少⼀次系统调⽤,也就减少了 2 次上下⽂切换的开销。

这样就只有 2 次上下⽂切换,和 3 次数据拷⻉


但是这还不是真正的零拷⻉技术,如果⽹卡⽀持 SG-DMA(The Scatter-Gather DirectMemory Access)技术(和普通的 DMA 有所不同),我们可以进⼀步减少通过 CPU 把内核缓冲区⾥的数据拷⻉到 socket 缓冲区的过程。

Linux运行这条命令查看网卡是否支持 SG-DMA

$ ethtool -k eth0 | grep scatter-gather
scatter-gather: on

7736f8c3c3384e97b1fc97df7d1e992e.png

这样,最终只有2次上下文切换和2 次数据拷⻉

四、PageCache

零拷⻉技术是基于 PageCache 的

零拷贝第⼀步都是先需要先把磁盘⽂件数据拷⻉「内核缓冲区」⾥,这个「内核缓冲区」实际上是磁盘⾼速缓存(PageCache)

通常,刚被访问的数据在短时间内再次被访问的概率很⾼,于是我们可以⽤ PageCache 来缓存最近被访问的数据,所以,读磁盘数据的时候,优先在 PageCache 找。

但是针对⼤⽂件的传输,不应该使⽤ PageCache,也就是说不应该使⽤零拷⻉技术,因为可能由于 PageCache 被⼤⽂件占据,由于⼤⽂件难以命中 PageCache 缓存,⽽导致「热点」⼩⽂件⽆法利⽤到 PageCache,这样在⾼并发的环境下,会带来严重的性能问题。


传输⼤⽂件的时候,使⽤「异步 I/O + 直接 I/O」,因为可以绕过PageCache;

传输⼩⽂件的时候,则使⽤「零拷⻉技术」;

在 nginx 中,我们可以⽤如下配置,来根据⽂件的⼤⼩来使⽤不同的⽅式:

location /video/ {
sendfile on;
aio on;
directio 1024m;
}

当⽂件⼤⼩⼤于 directio 值后,使⽤「异步 I/O + 直接 I/O」,否则使⽤「零拷⻉技术」。

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
目录
相关文章
|
15天前
|
存储 安全 固态存储
计算机启动:从插上电源到操作系统启动的全过程
当我们插上电源,计算机从休眠状态苏醒,直至操作系统完全启动,这一系列复杂的过程涉及到硬件和软件的多个层面。本文将详细解析计算机插上电源后操作系统所做的工作,揭示这一过程的技术细节。
23 6
|
7月前
|
存储 Unix Linux
手写操作系统(4)——计算机是如何启动的?BIOS、GRUB、文件系统......
手写操作系统(4)——计算机是如何启动的?BIOS、GRUB、文件系统......
127 1
|
4月前
|
存储 算法 网络协议
了解操作系统的基本原理和常见操作,提高计算机使用效率
了解操作系统的基本原理和常见操作,提高计算机使用效率
53 4
|
4月前
|
运维 安全 Linux
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
|
5月前
|
Linux 调度
部署02-我们一般接触的是Mos和Wimdows这两款操作系统,很少接触到Linux,操作系统的概述,硬件是由计算机系统中由电子和机械,光电元件所组成的,CPU,内存,硬盘,软件是用户与计算机接口之间
部署02-我们一般接触的是Mos和Wimdows这两款操作系统,很少接触到Linux,操作系统的概述,硬件是由计算机系统中由电子和机械,光电元件所组成的,CPU,内存,硬盘,软件是用户与计算机接口之间
|
6月前
|
运维 安全 Linux
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
|
7月前
|
存储 算法 Linux
【计算机操作系统】深入探究CPU,PCB和进程工作原理
【计算机操作系统】深入探究CPU,PCB和进程工作原理
203 1
|
7月前
|
监控 Linux 调度
操作系统学习笔记(一)
在Linux中,使用`ps -aux | grep PID`来查看特定进程的状态,或者用`top`指令监控进程和内存。通过`cat 文件名 | grep 关键词`或`grep -i 关键词 文件名`搜索日志文件。`grep`是一个强大的文本搜索工具,支持多种参数,如`-i`忽略大小写,`-c`计数,`-f`从文件读取关键词。要临时更改主机名用`hostname 新主机名`,永久更改则用`hostnamectl set-hostname 新主机名`
47 0
|
7月前
|
消息中间件
操作系统学习笔记(二)
进程切换比线程切换更消耗资源,因为进程切换需保存更多上下文,包括地址空间、寄存器、栈和文件描述符等,还要刷新TLB。线程切换仅需切换硬件上下文和内核栈,上下文更小,所以开销低。进程间通信有多种方式,如匿名管道(父子进程间)、命名管道(无亲缘关系进程)、信号、消息队列、共享内存和信号量等。这些通信方法各有特点,适用于不同场景。例如,匿名管道是半双工的,有名管道允许任何进程通过路径通信,信号用于进程间的简单通知,消息队列支持随机查询和按类型读取,共享内存允许多进程共享数据,而信号量则用于同步和控制对共享资源的访问。
45 0
|
7月前
|
存储 缓存 安全
【linux基础(八)】计算机体系结构--冯诺依曼系统&操作系统的再理解
【linux基础(八)】计算机体系结构--冯诺依曼系统&操作系统的再理解

热门文章

最新文章