零拷贝技术(zero copy),DMA,mmap,sendfile

在一些高性能的IO场景下我们经常能听到零拷贝技术,这是个不错的话题。

零拷贝指的是内核态与用户态之间的数据拷贝,而这两个区域的数据拷贝只能依靠CPU,但是CPU最重要的作用应该是运算。

一、DMA的由来

在没有DMA之前,磁盘的IO是这样的。

在这里插入图片描述

  • 用户进程调用read操作,CPU收到指令后,发出对应的指令给磁盘控制器,然后返回。
  • 磁盘控制器收到指令后,于是就开始准备数据,会把数据放入到磁盘控制器的内部缓冲区中,然后产生一个中断。
  • CPU收到中断信号后,停下手头的工作,接着把磁盘控制器的缓冲区的数据一次一个字节地读进自己的寄存器,然后再把寄存器里的数据写入到内存,而在数据传输的期间CPU 是无法执行其他任务的。

可以看到整个过程占用了大量的CPU时间,如果数据量大的话那整个的性能将不敢想象。

如果将这种搬运数据的工作交给单独的组件来执行,那么就可以解放CPU,使其专注于运算。于是就有了 DMA (直接内存访问 Direct Memory Access),顾名思义,就是允许外部设备直接读写内存,既不通过CPU,也不需要CPU干预。主存和DMA控制器之间有一条数据通路,因此主存和I/O设备之间交换信息时,不通过CPU。在数据块传送时,主存地址的确定、传送数据的计数等都由外设的硬件电路直接实现。主存中要开辟专用缓冲区,及时供给和接收外设的数据。

有了DMA之后传输数据就变成了
在这里插入图片描述

二、文件传输案例

在不适用任何零拷贝技术的情况下,我们将一个文件从服务器上发送给客户端的过程大致如下。

在这里插入图片描述

要经过两次系统调用(read & write)加四次数据拷贝,而每次系统调用都有两次用户态和内核态的切换。具体看图。

三、如何实现零拷贝

1、mmap (memory-map)

它可以把文件映射到进程的虚拟内存空间。通过对这段内存的读取和修改,可以实现对文件的读取和修改,而不需要用read和write系统调用,但是这一切都需要操作系统在幕后工作(异步处理)。如下图所示,为mmap实现原理的示意图。

在这里插入图片描述

可以看到,用户进程空间中某一块虚拟内存与内核中的物理内存(PageCache)形成映射,而这块物理内存与目标文件的某一块形成映射。用户进程读取文件的过程不是传统的read系统调用,而是直接访问的PageCache,如果没有数据,系统会把文件的内容读取过来缓存起来,应该说就是利用的内核中的缓存区。

为什么传统的read操作会有一个从内核缓存中把数据拷贝到用户态的操作呢,我的理解是,内核态中的数据属于高速缓存,在有效期内它可以被重复读取,向用户态中拷贝一份也是方便各自程序区处理数据,形成隔离效果。

void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);

addr:指定映射的起始地址,通常设为NULL,由内核来分配
length:代表将文件中映射到内存的部分的长度。
prot:映射区域的保护方式。可以为以下几种方式的组合:
    PROT_EXEC 映射区域可被执行
    PROT_READ 映射区域可被读取
    PROT_WRITE 映射区域可被写入
    PROT_NONE 映射区域不能存取
flags:映射区的特性标志位,常用的两个选项是:
    MAP_SHARD:写入映射区的数据会复制回文件,且运行其他映射文件的进程共享
    MAP_PRIVATE:对映射区的写入操作会产生一个映射区的复制,对此区域的修改不会写会原文件
fd:要映射到内存中的文件描述符,有open函数打开文件时返回的值。
offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
函数返回值:实际分配的内存的起始地址。

与mmap函数成对使用的是munmap函数,它是用来解除映射的函数

int munmap(void *start, size_t length)
    
start:映射的起始地址
length:文件中映射到内存的部分的长度
返回值:解除成功返回0,失败返回-1
package main

import (
	"fmt"

	"golang.org/x/exp/mmap"
)

func main() {
	at, _ := mmap.Open("./tmp.txt")
	defer at.Close()
	buf := make([]byte, 1024)
	at.ReadAt(buf, 0)
	fmt.Println(string(buf))
}

mmap 除了减少一次数据拷贝外,还有一个优势在于,不同的虚拟内存地址可以指向同一个物理内存,这样多个进程之间就可以来共享这块数据。

在这里插入图片描述

2、sendfile

在 Linux 内核版本 2.1 中,提供了一个专门发送文件的系统调用函数 sendfile()。

#include <sys/socket.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

它的前两个参数分别是目的端和源端的文件描述符,后面两个参数是源端的偏移量和复制数据的长度,返回值是实际复制数据的长度。

该系统调用直接把内核缓冲区里的数据拷贝到 socket 缓冲区里,不再拷贝到用户态。不管怎么说,文件内容是要先读到内核缓存中才能进行其他操作。

在这里插入图片描述

sendfile 的应用场景是:用户从磁盘读取一些文件数据后不需要经过任何计算与处理就通过网络传输出去。此场景的典型应用是消息队列。

3、sendfile + SG-DMA

linux2.4版本后,对sendfile做了优化升级,引入SG-DMA技术,其实就是对DMA拷贝加入了scatter-gather操作,它可以直接从内核空间缓冲区中将数据读取到网卡,这样的话还可以省去CPU拷贝。注意,SG-DMA技术只有网卡支持(通过命令ethtool -k eth0 | grep scatter-gather查看)。

在这里插入图片描述

可以发现sendfile + DMA scatter/gather实现的零拷贝发生了2次上下文切换以及2次数据拷贝,这就是真正的零拷贝技术,全程没有通过CPU来搬运数据,所有的数据都是通过DMA进行传输的。

三、Golang实现零拷贝

1、mmap
package main

import (
	"fmt"

	"golang.org/x/exp/mmap"
)

func main() {
	at, _ := mmap.Open("./tmp.txt")
	defer at.Close()
	buf := make([]byte, 1024)
	at.ReadAt(buf, 0)
	fmt.Println(string(buf))
}
2、sendfile

暂时没有找到Golang如何调用sendfile。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

武汉星起航:欧洲市场巨擘,亚马逊欧洲站重塑全球电商格局

在全球电商的浩瀚星海中&#xff0c;亚马逊欧洲站如一颗耀眼星辰&#xff0c;其卓越服务、海量用户群及尖端的物流网络熠熠生辉。在英国、德国、法国、意大利和西班牙这五大欧洲经济强国中&#xff0c;亚马逊凭借其无与伦比的市场领导力和消费者信任&#xff0c;稳固地占据了电…

个人网站搭建-步骤(持续更新)

域名申请 域名备案 域名解析 服务器购买 端口转发 Nginx要在Linux上配置Nginx进行接口转发&#xff0c;您可以按照以下步骤进行操作&#xff1a; 安装Nginx&#xff08;如果尚未安装&#xff09;&#xff1a; 使用包管理工具&#xff08;如apt, yum, dnf, 或zypper&#x…

PLC数据采集案例

--------天津三石峰科技案例分享 项目介绍 项目背景 本项目为天津某钢铁集团下数字化改造项目&#xff0c;主要解决天津大型钢厂加氢站数字化改造过程中遇到的数据采集需求。项目难点PLC已经在运行了&#xff0c;需要采集里面数据&#xff0c;不修改程序&#xff0c;不影响P…

C++编程(五)单例模式 友元

文章目录 一、单例模式&#xff08;一&#xff09;概念&#xff08;二&#xff09;实现方式1. 饿汉式2. 懒汉式 二、友元&#xff08;一&#xff09;概念&#xff08;二&#xff09;友元函数1.概念2.语法格式3. 使用示例访问静态成员变量访问非静态成员变量 &#xff08;三&…

Vue3.3 的 defineOptions 的使用,方便在 setup 语法糖中为组件命名和控制父子属性透传,包含在线运行实例欧

defineOptions 是 Vue3.3 的新的宏&#xff0c;可以通过 defineOptions 宏在 <script setup> 中使用选项式 API&#xff0c;也就是说可以在一个宏函数中设置 name, props, emits, render, 控制是否允许父子非 props 的属性透传等功能。 defineOptions 可以直接在 setup …

uni-app picker多列选项

预期实现的效果&#xff1a; 选中后的效果&#xff1a; // Dom部分 <template><picker mode"multiSelector" :range"ssqRange" range-key"name" columnchange"ssqColumnChange" change"ssqChange" class"p…

【ajax实战05】文章封面发布

一&#xff1a;实现效果 二&#xff1a;实现步骤 1 准备标签结构和样式 html结构样式 <div class"cover"><label for"img">封面&#xff1a;</label><label for"img" class"place"></label><inpu…

如何精准分析人形机器人运动数据?

全球“机器换人”进程加速,人形机器人有望成为AI下一个重要落地应用场景;EtherCAT-Analyzer具备分析人形机器人所有关节和电池与主站的通讯信息,快速掌握节点网络状态! 前言 随着人形机器人行业的发展及《中国制造2025》的全面实施,传统的脉冲模式控制很大程度上制约了机…

当了面试官才知道:做好这3点,面试成功率至少提高50%

关于辉哥&#xff1a; 资深IT从业者&#xff0c; 曾就职于阿里、腾讯、美团、中信科等互联网公司和央企&#xff1b; 两岁小男孩的父亲。 不定期分享职场 | 婚姻 | 育儿 | 个人成长心得体会 关注我&#xff0c;一起学习和成长。 最近作为公司社招面…

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include"CommunityToolkit.Mvvm" Version"8.2.2" /><PackageReference Include"Microsoft.Extensions.Hosting" Version"8.0.0" /><PackageReference Include&q…

必应bing搜索广告投放介绍,投放的广告形式和效果

必应Bing搜索广告以其独特的市场定位、高质量的用户群体和强大的全球覆盖能力&#xff0c;成为众多企业拓展业务、提升品牌影响力的重要渠道。作为微软旗下的一款搜索引擎&#xff0c;必应不仅在美国市场占据重要份额&#xff0c;其在全球范围内的影响力也不容小觑。对于寻求国…

MySQL 基础概念

MySQL逻辑架构 MySQL 服务器逻辑架构图 最上层的服务并不是MySQL所独有的&#xff0c;大多数基于网络的客户端/服务器的工具或者服务都有类似的架构&#xff0c;比如连接管理、授权认证、安全等等。 大多数MySQL的核心服务都在第二层&#xff0c;包括查询解析、分析、优化、…

【JavaEE进阶】Spring AOP使用篇

目录 1.AOP概述 2.SpringAOP快速入门 2.1 引入AOP依赖 2.2 编写AOP程序 3. Spring AOP详解 3.1 Spring AOP 核心概念 3.1.1切点(Pointcut) 3.1.2 连接点 (Join Point) 3.1.3 通知(Advice) 3.1.4 切面(Aspect) 3.2 通知类型 3.3PointCut 3.4 切面优先级 3.5 切点表…

经典神经网络(13)GPT-1、GPT-2原理及nanoGPT源码分析(GPT-2)

经典神经网络(13)GPT-1、GPT-2原理及nanoGPT源码分析(GPT-2) 2022 年 11 月&#xff0c;ChatGPT 成功面世&#xff0c;成为历史上用户增长最快的消费者应用。与 Google、FaceBook等公司不同&#xff0c;OpenAI 从初代模型 GPT-1 开始&#xff0c;始终贯彻只有解码器&#xff0…

安卓webview内h5页面调用录音设置

h5页面调用录音接口getUserMeia在webview中有可能不成功&#xff0c;进入错误回调&#xff0c;这个时候webview尽可能设置下面这些权限就会好。

Linux系统编程(七)进程间通信IPC

进程间通讯的7种方式_进程间通信的几种方法-CSDN博客 管道 pipe&#xff08;命名管道和匿名管道&#xff09;&#xff1b;信号 signal&#xff1b;共享内存&#xff1b;消息队列&#xff1b;信号量 semaphore&#xff1b;套接字 socket&#xff1b; 1. 管道 内核提供&#x…

华为云安全防护,九河云综合分解优劣势分析

随着全球化的发展&#xff0c;越来越多的企业开始寻求在国际市场上扩展业务&#xff0c;这一趋势被称为企业出海。然而&#xff0c;企业在海外扩张面临诸多隐患与安全挑战&#xff0c;其中因为地域的不同&#xff0c;在安全性方面与国内相比会变得薄弱&#xff0c;从而导致被黑…

展开说说:Android列表之RecyclerView

RecyclerView 它是从Android5.0出现的全新列表组件&#xff0c;更加强大和灵活。用于显示列表形式 (list) 或者网格形式 (grid) 的数据&#xff0c;替代ListView和GridView成为Android主流的列表组件。可以说Android客户端只要有表格的地方就有RecyclerView。 RecyclerView 内…

无痛接入FastText算法进行文本分类(附代码)

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

未来已来,如何打造智慧养殖场?

近年来&#xff0c;国家出台了一系列扶持政策&#xff0c;以促进养殖行业高质量发展&#xff0c;推动行业转型升级。在国家政策和市场需求的双重驱动下&#xff0c;养殖行业正迎来前所未有的发展机遇。智慧养殖以其高效、智能和可持续的特点&#xff0c;正逐步取代传统养殖方式…