首页 > 其他分享 >零拷贝

零拷贝

时间:2023-10-25 10:45:15浏览次数:26  
标签:sendfile DMA 内核 缓冲区 拷贝 CPU

零拷贝

Refs

用户缓冲区与内核缓冲区

sendfile

DMA,映射,零拷贝, JavaNIO

传统IO

cpu先从磁盘读取数据到内核缓冲区,然后拷贝到用户缓冲区。表现在代码中就是读取的时候先new一个buffer数组,然后读取进去。

如图,其中上下文切换和CPU拷贝是零拷贝主要优化的点。

image-20231025101256325

一共四次上下文切换,两次CPU拷贝,两次DMA拷贝。

零拷贝概念

零拷贝并不是没有拷贝数据,而是减少用户态/内核态的切换次数以及CPU拷贝的次数。零拷贝实现有多种方式,分别是

  • mmap+write
  • sendfile
  • 带有DMA收集拷贝功能的sendfile

注意:他们功能不全相同,后两者主要用于用户不需要操作数据的情况,因为只有内核在操作数据。

mmap

mmap()(系统调用)作用是将内核缓冲区和用户缓冲区的虚拟内存映射到同样的物理内存,这样,读取数据的时候就不用从内核缓冲区拷贝到用户缓冲区了。其他部分不变。如图:

减少一次拷贝。

image-20231025101659623

sendfile

sendfile()主要用于不用操作数据的情况,内核直接将数据拷贝到socket缓冲区,这样只需要两次内核用户态切换。如图

减少两次上下文切换和两次CPU拷贝。

image-20231025101854058

DMA+sendfile

sendfile()的优化由DMA支持,DMA可以根据文件描述符和长度在内存和外设进行数据拷贝。那么CPU只需要将核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区。然后DMA去拷贝到网卡中即可。

减少两次上下文切换和三次CPU拷贝。

image-20231025102110408

JavaNIO与零拷贝

FileChannel的transferTo()/transferFrom(),底层就是sendfile() 系统调用函数。

Java NIO有一个MappedByteBuffer的类,可以用来实现内存映射。它的底层是调用了Linux内核的mmap的API。

标签:sendfile,DMA,内核,缓冲区,拷贝,CPU
From: https://www.cnblogs.com/BayMax0-0/p/17786548.html

相关文章

  • [转]VS2019生成项目文件.lib或.dll或exe后如何拷贝到指定的目录文件夹
    VS2019编译CloudCompare,发现生成的项目文件都是分开的,每个项目下都有自己的文件夹Debug/Release,生成Dll都放在这些单独的项目文件夹内。目标(1)通常,我们要求所有的dll和.exe都在同一个文件夹,这样调试的时候就不用再去拷贝或设置环境变量,直接设置任意.exe项目为启动项目就能调试了......
  • Java基础 字节缓冲流、字节缓冲流拷贝文件
    字节缓冲流:原理:底层自带了长度为8192的缓冲区。利用缓冲区可以一次读写8192个字节,从而提高性能public BufferedInputStream(InputStream is)  →  把基本流包装成高级流,提高读取数据的性能public BufferedOutputStream(OutputStream os)  →  把基本......
  • 数组的拷贝与扩容
    数组的拷贝与扩容拷贝首先需要两个数组需要知道从哪里拷贝到哪里,拷贝多长//需求:从源数组里面拷贝第二个数组-第五个数组,到目标数组里面publicclassArrayCopyDemo{publicstaticvoidmain(String[]args){//源数组int[]ages={14,25,36,1......
  • 深入理解深浅拷贝
    深入理解深、浅拷贝(Java)​ 以下是个人理解,如有不足,请进行指正和补充,感谢您的阅读。​ 【参考】https://cloud.tencent.com/developer/article/2158401?areaId=106001一、什么是拷贝?​ 拷贝(中文对copy的音译),意思是复制。复制的话,大家应该都很清楚,这里就不作详细解释,意思就是生......
  • 给定文件列表,按目录结构拷贝到新目录中
      #!/bin/bash#mycopyTree.sh文件内容如下functionprint_usage(){echo"Usage:${1}<src_list_file><dest_dir>"}functionmycopy_tree(){#输入源文件列表目录src_list_file=${1}#输入目标目录dest_dir=${2}#遍历源文件......
  • Python:深拷贝与浅拷贝
    python:深拷贝与浅拷贝一、了解几个概念变量:是一个系统表的元素,拥有指向对象的连接空间对象:被分配的一块内存,存储所代表的值引用:是自动形成的从变量到对象的指针类型:属于对象,而非变量不可变对象:一旦创建就不可修改的对象(值内存地址固定后不可以再修改其值),包括字符......
  • Java基础 文件拷贝的基本代码
    FileInputStreamfis=newFileInputStream("E:\\Java基础资料\\a.txt");FileOutputStreamfos=newFileOutputStream("E:\\Java基础资料\\b.txt");while(true){intb=fis.read();if(b==-1)break;fos.write(b);}fos.close......
  • idea或者goland输出拷贝问题
    比如你拷贝一串很长的base字符串或者是json串,你会把\n也拷贝出来,这时候就很头疼,有2种解决方案,1是直接写文件,然后文件里copy出来2是借助vim,windows上面是gvim,查找\n,就能把隐藏的\n查出来,也算是一个小tips。......
  • 零拷贝
    目录零拷贝传统拷贝mmap(内存地址映射)+writekafka生态系统组成sendfilesendfile+DMAgathercopysplice+DMAcopy零拷贝传统拷贝read:当使用read调用来读取数据,此时会将用户态转化为内核态CPU对DMA控制器发起一个调用命令DMA将数据从硬盘拷贝到内核缓冲区中,拷贝完后......
  • docker cp 命令 - 宿主机与容器互相拷贝文件
    一、从容器拷贝文件到宿主机命令格式:$dockercp<containder-id>:/path/host/path例子:$dockercpc9b7f17d43e9:/opt/hello.txt/home/hello.txt二、从宿主机拷贝文件到容器命令格式:$dockercp/host/path<containder-id>:/path例子:$dockercp/home/hel......