首页 > 其他分享 >零拷贝

零拷贝

时间:2024-06-11 15:14:12浏览次数:19  
标签:文件 映射 mmap 内核 拷贝 数据

普通流程

网络IO读写流程应用进程的每一次写操作,都会把数据写到用户空间的缓冲区中,再由 CPU 将数据拷贝到系统内核的缓冲区中,之后再由 DMA 将这份数据拷贝到网卡中,最后由网卡发送出去。这里我们可以看到,一次写操作数据要拷贝两次才能通过网卡发送出去,而用户进程的读操作则是将整个流程反过来,数据同样会拷贝两次才能让应用程序读取到数据。应用进程的一次完整的读写操作,都需要在用户空间与内核空间中来回拷贝,并且每一次拷贝,都需要 CPU 进行一次上下文切换(由用户进程切换到系统内核,或由系统内核切换到用户进程),这样是不是很浪费 CPU 和性能呢?那有没有什么方式,可以减少进程间的数据拷贝,提高数据传输的效率呢?

所谓的零拷贝,就是取消用户空间与内核空间之间的数据拷贝操作,应用进程每一次的读写操作,都可以通过一种方式,让应用进程向用户空间写入或者读取数据,就如同直接向内核空间写入或者读取数据一样,再通过 DMA 将内核中的数据拷贝到网卡,或将网卡中的数据 copy 到内核。

零拷贝有两种解决方式,分别是 mmap+write 方式和 sendfile 方式,mmap+write方式的核心原理就是通过虚拟内存来解决的。

mmap(Memory-mapped file)

mmap(Memory-mapped file)是一种在内存和文件之间建立映射关系的技术。它允许将文件的一部分或整个文件映射到进程的地址空间,使得进程可以像访问内存一样直接读写文件数据。 使用mmap技术进行文件映射,可以带来一些优势和灵活性: 1. 零拷贝操作:mmap技术避免了数据在内核空间和用户空间之间的拷贝,从而提高了文件I/O的效率。当进程访问映射区域时,数据直接在内存中进行读写,减少了不必要的数据复制操作。 2. 文件缓存:映射文件的数据可以利用操作系统的文件缓存机制。如果多个进程都映射了同一个文件,它们可以共享同一个缓存,减少了磁盘I/O的次数,提高了整体性能。 3. 随机访问:通过映射文件到内存,进程可以直接访问文件的任意部分,而无需按照顺序逐步读取。这使得随机访问文件变得更加高效。 4. 内存映射:映射文件到内存后,可以将文件视为一块连续的内存区域进行操作。这使得对文件的读写操作变得更加灵活和方便。

sendfile

数据根本不经过用户态,直接从内核缓冲区进入到 Socket Buffer,同时,由于和用户态完全无关,就减少了一次上下文切换。

mmap 和 sendFile 的区别

  1. mmap 适合小数据量读写,sendFile 适合大文件传输。
  2. mmap 需要 4 次上下文切换,3 次数据拷贝;sendFile 需要 2 次上下文切换,最少 2 次数据拷贝。
  3. sendFile 可以利用 DMA 方式,减少 CPU 拷贝,mmap 则不能(必须从内核拷贝到 Socket 缓冲区)。

在这个选择上:rocketMQ 在消费消息时,使用了 mmap。kafka 使用了 sendFile。

 

标签:文件,映射,mmap,内核,拷贝,数据
From: https://www.cnblogs.com/zhengbiyu/p/18242051

相关文章

  • Python中的浅拷贝与深拷贝
    Python中值的拷贝可分为直接赋值,浅拷贝与深拷贝直接赋值:即为对象的引用,赋值前后的对象均指向同一对象浅拷贝:拷贝父对象,拷贝前与拷贝后的对象均为独立的对象,但是他们的子对象都仍然指向同一对象深拷贝:完全拷贝父对象及子对象,拷贝前与拷贝后的对象均独立存在演示代码如下import......
  • 2024-06-05 拷贝、函数、装饰器、迭代生成器
    一、浅拷贝lists=[1,2,[6]]内存空间不同,浅拷贝内容不变 new_lists=copy(lists)lists.append(7)print(lists,new_lists)//[1,2,[6],7][1,2,[6]]改变列表中内容,内存空间相同,数值改变new_lists=copy(lists)lists[-1].append(7)print(lists,new_lists)//[......
  • C++Primer Plus 第12章 类和动态内存分配 12.10编程练习第2题new,delete的指向深度拷
    系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:本章练习第2题涉及标准函数及关键词toupper,tolower(),strcpy_s(),strcat_s(),strcmp,strlen(),new[],delete[].实现如下效果输出应与下面相似:Pleaseenteryourname:FrettaFarboMynameis......
  • 文件IO——用read与write实现图片拷贝
    1#include<stdio.h>2#include<sys/types.h>3#include<sys/stat.h>4#include<fcntl.h>5#include<unistd.h>6#include<string.h>7intmain(intargc,constchar*argv[])8{910intpath=......
  • C++Primer Plus 第12章 类和动态内存分配 12.10编程练习第1题new,delete的指向深度拷
    C++PrimerPlus第12章类和动态内存分配12.10编程练习第1题`提示:练习一定要动手操作涉及标准函数及关键词1,new[],delete[],strlen(),strcpy_s(),cout,endl,explicit例如:1,对于下面的类的声明:`提示:设计数组和字符串的new,delete文章目录C++PrimerPlus第12章类......
  • 基本类型值,是按值复制的,而不是按引用复制的。(深浅拷贝)
    letobj=[1,2,4]letobj2=Array.from(obj)obj2[0]=23console.log(obj)这是浅拷贝吗?在给出的例子中,Array.from(obj) 实际上执行的是对数组 obj 的浅拷贝。这是因为数组在JavaScript中是一种特殊的对象,其元素存储在索引属性中。Array.from() 方法创建了一个新的数组实例......
  • python 深浅拷贝
    浅拷贝copy函数就是浅拷贝copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝对拷贝的对象开辟新的内存空间进行存储,子对象不会开辟新的空间list1=[1,2,3]list2=['a',list1]list3=list2.copy()print(id(list1))print(id(list2))#三个id都不一样prin......
  • 美团面试:说说Netty的零拷贝技术?
    零拷贝技术(Zero-Copy)是一个大家耳熟能详的技术名词了,它主要用于提升IO(Input&Output)的传输性能。那么问题来了,为什么零拷贝技术能提升IO性能?1.零拷贝技术和性能在传统的IO操作中,当我们需要读取并传输数据时,我们需要在用户态(用户空间)和内核态(内核空间)中进行数据拷贝,它的执......
  • 浅拷贝与深拷贝
    浅拷贝过程最大的问题是共享同一块内存,容易引发内存问题,下面这个例子就是浅拷贝在析构的时候出现段错误。#include<iostream>#include<cstring>//forstrcpy_s#include<thread>classMyClass{public:char*data;MyClass(constchar*str){d......
  • 用fscanf\fprintf fgetc\fputc fgets\fputs实现文件拷贝。
     1.fscanf\fprintf#include<stdio.h>intmain(intargc,constchar*argv[]){FILE*fp=fopen("./1.c","r");if(NULL==fp){perror("fopen");return-1;}FILE*fp1=fopen......