linux内核视角看零拷贝

一、什么是零拷贝?

在很多性能优化方案中都有提到零拷贝,零拷贝到底是怎么回事,是真的没有数据的拷贝吗?零拷贝(Zero-copy)是一种数据传输技术,旨在减少数据在内核态和用户态之间的复制操作。其实并不是真的没有数据的拷贝。

二、内核发送数据包

2.1 网卡启动准备

linux启动的时候,在网卡能够收发数据包之前,要做很多准备工作。比如ksoftirqd内核线程的创建,注册好协议处理函数,网卡驱动初始化等。这些初始化工作完成后,就可以启动网卡了。网卡启动的时候,会创建好RingBuffer,现在的服务器上的网卡一般都是支持多队列的,每一个队列都是由一个RingBuffer表示
在这里插入图片描述

2.2 数据包发送

整体流程是:用户数据被拷贝到内核态,然后经过协议栈处理后进入网卡RingBuffer,网卡驱动真正将数据发送出去,当发送完成时,网卡发起硬中断来通知CPU,最后清理RingBuffer。

2.2.1 协议栈处理

在这里插入图片描述
用户进程进行系统调用时,找到内核的socket对象,之后进入内核协议栈处理。

在进入协议栈inet_sendmsg函数后,内核会找到socket对象上具体的协议发送函数,对于TCP协议就是tcp_sendmsg。

//file: net/ipv4/tcp.c
int tcp_sendmsg(...){while(...){......//申请内核态内存skbskb = sk_stream_alloc_skb(...);//把skb挂到socket的发送队列上,sk就是socketskb_entail(sk,skb);......//将用户空间的数据拷贝到skb,from是用户空间的数据地址skb_add_data_nocache(sk,skb,from,copy);}
}

在这里插入图片描述
注意:在协议栈处理这里,完成了一次用户数据到内核socket对象发送队列的拷贝。

2.2.1.1 传输层处理
//file: net/ipv4/tcp_output.c
static bool tcp_write_xmit(...){//循环从socket发送队列获取待发送skbwhile((skb = tcp_send_head(sk))){......//传输层发送tcp_transmit_skb(sk,skb,1,gfp);}
}
//file net/ipv4/tcp_output.c
static int tcp_transmit_skb(...){//循环socket发送队列克隆出新的skbif(likely(clone_it)){skb = skb_clone(skb,gfp_mask);......}//封装TCP头th = tcp_hdr(skb);th->source  =  inet->inet_sport;th->dest    =  inet->inet_dport;......//调用网络层发送接口ip_queue_xmit(...);
}

在这里插入图片描述
这里需要注意的是:传输层需要从socket发送队列克隆一个新的skb,那么为什么要复制一个skb出来?这是因为skb后续在调用网络层,最后到达网卡发送完成的时候,这个skb会被释放掉。而TCP协议是支持丢失重传的,在收到对方的ACK之前,socket发送队列上的skb不能被删除,等收到ACK再真正删除。 因此,传输层从socket发送队列拷贝skb也是不能少的。
自此,传输层的工作都完成了。数据离开传输层,接下来将会进入内核网络层的处理。

2.2.1.2 网络层处理
//file: net/ipv4/ip_output.c
int ip_queue_xmit(...){......//为skb设置路由表,路由表可以查到目的网络应该通过哪个网卡,哪个网关发送出去skb_dst_set_noref(skb,&rt->dst);//设置IP头iph = ip_hdr(skb);iph->protocol  = sk->sk_protocol;......//发送ip_local_out(skb);
}

在这里插入图片描述
如果使用iptables配置了一些规则,那么这里将检测是否命中规则,如果设置复杂的netfiler规则,将会增大CPU开销。

2.2.1.3 邻居子系统处理

邻居子系统是位于网络层和数据链路层中间的一个系统,其作用是为网络层提供一个下层的封装,让下层决定发送到哪个MAC地址。
在这里插入图片描述

2.2.1.4 网络设备子系统处理

在这里插入图片描述
QDisc(queueing discipline )位于IP层和网卡的ringbuffer之间。ringbuffer是一个简单的FIFO队列,这种设计使网卡的驱动层保持简单和快速。而QDisc实现了流量管理的高级功能,包括流量分类,优先级和流量整形(rate-shaping)。

2.2.1.5 网卡驱动处理

在驱动函数中,会将skb挂到RingBuffer上,并且将skb数据映射到网卡可以访问的DMA内存区域。最后驱动会触发真实的数据发送。

三、零拷贝到底是怎么回事?

传统的read + send系统调用:
在这里插入图片描述
sendfile系统调用:

在sendfile系统调用中,数据不需要拷贝到用户空间,用户进程可直接操作内核Page Cache数据,减少了拷贝的次数,所以,零拷贝并不是说完全没有数据拷贝。java的fileChannel.transferTo()底层就是sendfile系统调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/691871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络概论和数据通信基础

文章目录 计算机网络概论从物理构成上看,计算机网络包括硬件、软件和协议三大部分计算机网络的功能组成计算机网络的分类网络体系结构分层与体系结构接口、协议和服务数据传送单位OSI模型TCP/IP模型 数据通信基础数字信号调制为模拟信号正交振幅调制QAM 模拟数据编码…

将指定文件夹下的所有文件内容按规则进行替换

当我们遇到想要将某个文件夹及其子文件夹下的文件内容按规矩进行批量替换时,挨个打开文件进行替换会很浪费时间,于是写了这个powershell脚本。 1、首先创建一个XXX.ps1的文件并用记事本打开。 2、将以下代码复制到创建的文件中。 $folderPath "E:&…

JNI实现一组字节数组转IP地址、IP地址转数组的函数

为什么单独实现,这是因为JAVA标准库提供的函数有性能问题,它会走DNS查询有网络IO,而且还是同步阻塞的,无论是客户端还是服务器,这都应该是不被允许的行为。 JNI实现: bytes_to_address_string(byte[] addre…

C++ 遍历map的3中方法

方法1 #include <iostream> #include <string> #include <map> using namespace std;int main() {map<string, string> nameList {{"张三丰", "武当山"},{"张无忌", "光明顶"},{"张二蛋", "…

二叉树基本概念与遍历

什么是二叉树 二叉树不同于别的树&#xff0c;因为他每个节点最多只有两个子节点&#xff0c;而别的树可以有无数个子节点。 所以二叉树就是只最多只有两个子节点的树&#xff0c;一个子节点叫右子节点&#xff0c;另一个子节点叫左子结点 而他们的上一层就是父子节点&#xf…

航班进出港|航班进出港管理系统|基于springboot航班进出港管理系统设计与实现(源码+数据库+文档)

航班进出港管理系统目录 目录 基于springboot航班进出港管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 5、航班信息管理 &#xff08;1&#xff09; 航班信息管理 &#xff08;2&#xff09;起飞降落申请管理 &#xff08;3&#xff09;公告管理 &…

城市智慧驿站是什么?城市智慧驿站有哪些功能

城市智慧驿站作为一种创新性的社会配套设施&#xff0c;开始在多个城市落地使用&#xff0c;引起了社会的关注。 城市智慧驿站是什么&#xff1f;城市智慧驿站是在智慧城市的背景下&#xff0c;城市智慧驿站智慧公厕成为了一种创新性的社会配套建筑。作为景观式模块化建筑&…

UE蓝图 分支(Branch)节点和源码

系列文章目录 UE蓝图 Get节点和源码 UE蓝图 Set节点和源码 UE蓝图 Cast节点和源码 UE蓝图 分支(Branch)节点和源码 文章目录 系列文章目录一、分支节点功能二、分支节点用法三、分支节点使用场景四、分支节点实现过程五、分支节点相关源码 一、分支节点功能 在Unreal Engine&a…

Mysql数据库主从集群从库Slave因为RelayLog过多过大引起服务器硬盘爆满生产事故实战解决

Mysql数据库主从集群从库slave因为RelayLog过多过大引起从库服务器硬盘爆满生产事故实战解决 一、MySQL数据库主从集群概念 MySQL数据库主从集群是一种高可用性和读写分离的数据库架构&#xff0c;它基于MySQL的复制&#xff08;Replication&#xff09;技术来同步数据。在主…

【Kotlin】Kotlin流程控制

1 选择结构 Kotlin 中选择结构主要包含 if -else、when 语句&#xff0c;并且可以返回结果。 1.1 if-else 1.1. 条件选择 fun main() {var score 85if (score > 90) {println("优秀")} else if (score > 80) {println("良好")} else if (score &…

信息安全法律法规体系

信息安全法律法规体系 我国信息安全法规体系可以分为4层。 法律层面具体对应的法律、法规一般性法律规定宪法、国家安全法、国家秘密法、治安管理处理条例等虽然没有专门针对信息安全的条款,但约束了信息安全相关的行为规范和惩罚信息网络犯罪的法律《中华人名共和国刑法》《…

17.2 SpringMVC框架_Restful开发风格

Restful开发风格 1. Restful风格介绍1.1 传统Web应用1.2 REST与RESTful1.3 RESTful数据传输1.4 RESTful开发规范1.5 RESTful命名要求(❤❤)2. RESTful开发实战2.1 maven项目添加web应用2.2 依赖2.3 请求响应2.4 @RestController注解2.5 @PathVariable注解2.6 简单请求与非简单请…

如何交接一个前端项目

一.在非交接状态下&#xff0c;需要做好的事情 必要的代码注释必要的文档梳理 readme即可&#xff0c;记录重要的信息方便自己查阅、方便新的伙伴快速了解项目 二.交接readme 2.1项目相关的网址 项目git地址不同环境的访问权限&#xff08;或者对应的测试账号/密码&#xf…

MySQL篇之主从同步原理

一、原理 MySQL主从复制的核心就是二进制日志。 二进制日志&#xff08;BINLOG&#xff09;记录了所有的 DDL&#xff08;数据定义语言&#xff09;语句和 DML&#xff08;数据操纵语言&#xff09;语句&#xff0c;但不包括数据查询&#xff08;SELECT、SHOW&#xff09;语句。…

19-树-填充每个节点的下一个右侧节点指针 II

这是树的第19篇算法&#xff0c;力扣链接。 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。…

继ChatGPT后的又一王炸!Sora模型解析与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

Linux----防火墙之保存规则

一、关于iptables规则的保存 之前写的iptables的设置&#xff0c;但是都是临时生效的&#xff0c;一旦电脑重启&#xff0c;那么就会失效&#xff0c;如何永久保存&#xff0c;需要借助iptables-save命令&#xff0c;开机生效需要借助iptables-restore命令&#xff0c;并写入规…

“薪”的一年程序员裁员潮技术变革情况下 程序员就业机会在哪里?

引言&#xff1a;一对来自中国的工程师夫妻在美国的不幸身亡&#xff0c;疑似与谷歌的裁员有关&#xff0c;这一事件再次引发了人们对技术变革下裁员对程序员影响的关注。 一、针对裁员潮的一些看法 在我看来&#xff0c;技术变革对程序员的影响是双面的。一方面&#xff0c;…

代码随想录算法训练营day16

题目&#xff1a;104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数 参考链接&#xff1a;代码随想录 104.二叉树的最大深度 思路&#xff1a;上次是用层序遍历的思路做过。这次想一点不一样的思路&#xff0c;对于一个二叉树的最大深度其实即为其两个…

【Python机器学习】详解Python机器学习进行时间序列预测

&#x1f517; 运行环境&#xff1a;Python &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…