热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php零拷贝,百万并发「零拷贝」技术系列之初探门径

Wiki对零拷贝的定义Zero-copydescribescomputeroperationsinwhichtheCPUdoesnotperformthetaskofcopyi

07b1c22d093dd26593e9ae5f8821cd14.png

Wiki对零拷贝的定义

"Zero-copy" describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.

零拷贝(Zero-copy)是指在计算机执行操作时,CPU 不需要将数据从一块内存拷贝到另一块内存,减少拷贝次数可以提高性能。

在操作系统层面来说零拷贝是指不需要将数据从内核空间复制到用户空间,而Netty、Kafka等框架都因零拷贝而闻名著称,技术来不得半点马虎和一知半解,本着知其然知其所以然的态度,本系列为你揭秘其中原委和解决方案。

计算机组成

计算机是由硬件、内核和上层应用组成,通过它们在功能上由下而上的层层传递给用户提供各种服务,如下图所示。为了便于独立开发、调试和维护,采用了高内聚低耦合分层设计思想:内核负责对硬件直接操作,在封装硬件操作的同时给上层应用提供功能接口,承上启下;上层应用调用内核接口为用户提供业务服务。每一层都使用较低层提供的功能而不必知道其实现细节,只需了解其接口能做什么即可。

ee6de626eaa0f20f305b6489598784db.png

实际上随着时间的演进和功能的不断丰富,内核体积变得庞大不易管理,所以现代的操作系统基本都采用微内核的设计思想:把内核模块化,将非基础模块从内核中移除,把这些非基础模块实现为系统应用,甚至用户应用,从而减少内核的体积和复杂度,使其功能更聚焦。

微内核设计的好处颇多:

方便扩展内核,所有新的应用都可以在用户空间增加而不必修改内核;

由于大多数应用都是作为用户进程而非内核进程来运行的,为微内核提供了更好的安全性和可靠性;

微内核较小,开发、调试和维护工作量都相对较少,而且容易进行硬件平台移植;

然而微内核究竟包括哪些基础模块,实际上每个操作系统的处理并不相同,并没有定论和标准,但一般至少会包括进程、内存管理和通讯功能。

上层应用包含了系统应用和用户应用:系统应用一般跟随系统发行版而来,但也是通过调用内核接口开发的,一般是用于系统管理;用户应用是用户自行开发的应用,一般是为了实现自己的业务逻辑。但上层应用一般都采用高级语言来编写,为了降低复杂性和高效,高级语言对内核接口进行了封装,提供了编程语言类库,比如C语言的标准库、Java的JDK等。

用户空间和内核空间

用户进程不能直接操作硬件,只有通过内核提供的接口来操作,而为了确保内核的正常、安全地运行,不会因上层应用的异常导致内核陷入灾难,就必须区分内核代码执行和用户定义代码执行,也就是所谓的双重模式即: 内核态和用户态。 当用户程序正在执行,系统处于用户态,当用户程序需要调用内核功能,它必须通过系统调用的形式转换为内核态执行。 一般是通过硬件支持来区分两种模式的,在硬件中增加了一个模 式bit位: 0代表内核态,1代表用户态。

5534d10bf09e8a188cf68197b8772f55.png

系统通过引导程序,装入内核处于内核态,紧接着开始执行用户进程进入用户态(模式位为1),一旦遇到中断或系统调用,则又从用户态进入内核态(模式位为0),内核处理完后返回用户进程进入用户态(模式位为1),如上图。

进程是操作系统资源分配的最小单元,进程在执行上有用户态和内核态,那么虚拟内存也分为了用户空间和内核空间,供用户态和内核态的进程使用。比如32位的操作系统内存可以高达4G,把最高的1G字节(虚拟内存地址0xC0000000~0xFFFFFFFF)供内核使用,称为内核空间,而将较低的3G字节(虚拟内存地址 从0x00000000到0xBFFFFFFF)供上层应用使用,称为用户空间。

482a84ee8ac03deaba64863721297421.png

虚拟内存是相对于物理内存而言,操作系统会对物理内存进行映射和抽象,软件的所有操作都是对虚拟内存而言,也可以理解为物理内存映射为用户空间和内核空间。

当进程由用户态进行进入内核态,系统需要保存当前运行在CPU中进程的上下文,从而能在其处理完毕后转换为用户态时能恢复其上下文,这一任务称为上下文切换(context switch)。上下文切换在计算机执行期间会比较频繁,只要牵涉到内核态和用户态的转换就会涉及到上下文切换。所谓的上下文究竟是指什么呢?上下文从其英文context可知,是进行运行的环境,它包括进程的状态、计数器、全局变量、临时数据如函数参数、返回地址、局部变量等,还可能包括运行期间动态分配的内存堆(heap)。频繁的上下文切换,对数据的保存和恢复操作过于频繁,对性能的影响特别显著。

36b25a854deb3121530c84ec5b9af986.png

示例

为了全面理解用户空间、内核空间、用户态、内核态,我们举个例子来说明:读取文件内容并通过Socket发送。

997c5c59471701470ae2fa174bb8ed48.png

由于用户进程无法直接操作硬件,因此用户进程首先需要通过系统调用(System Call)来调用内核接口,此时的事件流如下

用户进程通过系统调用读取文件内容,由用户态进入内核态;

内核通过直接内存(DMA)的方式获取文件内容,并返回用户进程,由内核态转换用户态;

用户进程对数据进行处理后,通过系统调用Socket发送数据,由用户态进入内核态;

内核通过直接内存(DMA)的方式发送数据,并返回用户态;

由上图流程可知会经历4次上下文切换,而它的数据会也经历了4次拷贝,数据流向如下

9c7f40aa323cb02a666d113899e4f876.png

内核通过DMA方式,把文件内容拷贝到内核空间;

从内核空间通过CPU拷贝到用户空间,供用户进程使用;

用户处理完毕后,把数据从用户空间通过CPU拷贝到内核空间;

内核通过DMA方式拷贝到网卡发送;

什么是DMA

所有的硬件是通过控制器连接到计算机总总线,传统的中断式I/O方式是把数据拷贝到控制器寄存器,控制器再以中断的方式通知CPU拷贝到内存。由于这种方式频繁的中断,导致大量占用CPU时间片。DMA是Direct Memory Access的缩写,中文称之为直接存储器访问。它的使用方式是CPU通知DMA控制器进行I/O后CPU就被解脱出来做别的事情了,数据的拷贝过程都是由DMA来操作完成,数据拷贝完成后DMA控制器以中断的方式通知CPU。

写在最后

本篇我们了解了用户态、内核态、用户空间、内核空间的概念,而且从事件流和数据流我们也找到了提高性能的优化方向: 降低拷贝和上下文切换次数,下一篇我们将揭晓优化方案。

版权归@码农神说所有,转载须经授权,翻版必究

转载可联系助手,微信号:codeceo-01



推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
author-avatar
Fealty-小飞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有