Zero Copy

网络框架netpoll中的SO_ZEROCOPY https://www.163.com/dy/article/FS6AS7SS0518R7MO.html https://docs.kernel.org/networking/msg_zerocopy.htmlsend() with MSG_ZEROCOPYkernel v4.14 版本接受了来自 Google 工程师 Willem de Bruijn 在 TCP 网络报文的通用发送接口 send() 中实现的 zero-copy 功能 用户进程就能够把用户缓冲区的数据通过零拷贝的方式经过内核空间发送到网络 阅读详情

Zero Copy I: User-Mode Perspective

Author By Dragan Stancevic

Translated By Love. Katherine

 

(解释Linux中的"零拷贝"特性,为什么有用以及何处需要改进之处)

 

如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰到没有充分理解这个问题的人们。因此,我决定写一些文章略微深入的讲述这个问题,希望能将这个有用的特性解释清楚。在本文中,将从用户空间应用程序的角度来阐述这个问题,因此有意忽略了复杂的内核实现。

 

什么是”零拷贝”

 

为了更好的理解问题的解决法,我们首先需要理解问题本身。首先我们以一个网络服务守护进程为例,考虑它在将存储在文件中的信息通过网络传送给客户这样的简单过程中,所涉及的操作。下面是其中的部分简单代阿:

 

       read(file, tmp_buf, len);

       write(socket, tmp_buf, len);

 

看起来不能更简单了。你也许认为执行这两个系统调用并未产生多少开销。实际上,这简直错的一塌糊涂。在执行这两个系统调用的过程中,目标数据至少被复制了4次,同时发生了同样多次数的用户/内核空间的切换(实际上该过程远比此处描述的要复杂,但是我希望以简单的方式描述之,以更好的理解本文的主题)。

 

为了更好的理解这两句代码所涉及的操作,请看图1。图的上半部展示了上下文切换,而下半部展示了复制操作。

Figure 1. Copying in Two Sample System Calls

 

 

 

步骤一:系统调用read导致了从用户空间到内核空间的上下文切换。DMA模块从磁盘中读取文件内容,并将其存储在内核空间的缓冲区内,完成了第1次复制。

 

步骤二:数据从内核空间缓冲区复制到用户空间缓冲区,之后系统调用read返回,这导致了从内核空间向用户空间的上下文切换。此时,需要的数据已存放在指定的用户空间缓冲区内(参数tmp_buf),程序可以继续下面的操作。

 

步骤三:系统调用write导致从用户空间到内核空间的上下文切换。数据从用户空间缓冲区被再次复制到内核空间缓冲区,完成了第3次复制。不过,这次数据存放在内核空间中与使用的socket相关的特定缓冲区中,而不是步骤一中的缓冲区。

 

步骤四:系统调用返回,导致了第4次上下文切换。第4次复制在DMA模块将数据从内核空间缓冲区传递至协议引擎的时候发生,这与我们的代码的执行是独立且异步发生的。你可能会疑惑:“为何要说是独立、异步?难道不是在write系统调用返回前数据已经被传送了?write系统调用的返回,并不意味着传输成功——它甚至无法保证传输的开始。调用的返回,只是表明以太网驱动程序在其传输队列中有空位,并已经接受我们的数据用于传输。可能有众多的数据排在我们的数据之前。除非驱动程序或硬件采用优先级队列的方法,各组数据是依照FIFO的次序被传输的(图1中叉状的DMA copy表明这最后一次复制可以被延后)。

 

正如你所看到的,上面的过程中存在很多的数据冗余。某些冗余可以被消除,以减少开销、提高性能。作为一名驱动程序开发人员,我的工作围绕着拥有先进特性的硬件展开。某些硬件支持完全绕开内存,将数据直接传送给其他设备的特性。这一特性消除了系统内存中的数据副本,因此是一种很好的选择,但并不是所有的硬件都支持。此外,来自于硬盘的数据必须重新打包(地址连续)才能用于网络传输,这也引入了某些复杂性。为了减少开销,我们可以从消除内核缓冲区与用户缓冲区之间的复制入手。

 

消除复制的一种方法是将read系统调用,改为mmap系统调用,例如:

 

tmp_buf = mmap(file, len);

write(socket, tmp_buf, len);

 

为了更好的理解这其中设计的操作,请看图2。上下文切换部分与图1保持一致。

Figure 2. Calling mmap

 

 

步骤一:mmap系统调用导致文件的内容通过DMA模块被复制到内核缓冲区中,该缓冲区之后与用户进程共享,这样就内核缓冲区与用户缓冲区之间的复制就不会发生。

 

步骤二:write系统调用导致内核将数据从内核缓冲区复制到与socket相关联的内核缓冲区中。

 

步骤三:DMA模块将数据由socket的缓冲区传递给协议引擎时,第3次复制发生。

 

通过调用mmap而不是read,我们已经将内核需要执行的复制操作减半。当有大量数据要进行传输是,这将有相当良好的效果。然而,性能的改进需要付出代价的;是用mmap与write这种组合方法,存在着一些隐藏的陷阱。例如,考虑一下在内存中对文件进行映射后调用write,与此同时另外一个进程将同一文件截断的情形。此时write系统调用会被进程接收到的SIGBUS信号中断,因为当前进程访问了非法内存地址。对SIGBUS信号的默认处理是杀死当前进程并生成dump core文件——而这对于网络服务器程序而言不是最期望的操作。

有两种方式可用于解决该问题:

 

第一种方式是为SIGBUS信号设置信号处理程序,并在处理程序中简单的执行return语句。在这样处理方式下,write系统调用返回被信号中断前已写的字节数,并将errno全局变量设置为成功。必须指出,这并不是个好的解决方式——治标不治本。由于收到SIGBUS信号意味着进程发生了严重错误,我不鼓励采取这种解决方式。

 

第二种方式应用了文件租借(在Microsoft Windows系统中被称为“机会锁”)。这才是解劝前面问题的正确方式。通过对文件描述符执行租借,可以同内核就某个特定文件达成租约。从内核可以获得读/写租约。当另外一个进程试图将你正在传输的文件截断时,内核会向你的进程发送实时信号——RT_SIGNAL_LEASE。该信号通知你的进程,内核即将终止在该文件上你曾获得的租约。这样,在write调用访问非法内存地址、并被随后接收到的SIGBUS信号杀死之前,write系统调用就被RT_SIGNAL_LEASE信号中断了。write的返回值是在被中断前已写的字节数,全局变量errno设置为成功。下面是一段展示如何从内核获得租约的示例代码。

 

if(fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {

    perror("kernel lease set signal");

    return -1;

}

/* l_type can be F_RDLCK F_WRLCK */

if(fcntl(fd, F_SETLEASE, l_type)){

    perror("kernel lease set type");

    return -1;

}

 

在对文件进行映射前,应该先获得租约,并在结束write操作后结束租约。这是通过在fcntl调用中指定租约类型为F_UNLCK了来实现的。

 

Sendfile

 

sendfile系统调用在内核版本2.1中被引入,目的是简化通过网络在两个本地文件之间进行的数据传输过程。sendfile系统调用的引入,不仅减少了数据复制,还减少了上下文切换的次数。使用方法如下:

sendfile(socket, file, len);

 

为了更好的理解所涉及的操作,请看图3

Figure 3. Replacing Read and Write with Sendfile

 

步骤一:sendfile系统调用导致文件内容通过DMA模块被复制到某个内核缓冲区,之后再被复制到与socket相关联的缓冲区内。

 

步骤二:当DMA模块将位于socket相关联缓冲区中的数据传递给协议引擎时,执行第3次复制。

 

你可能会在想,我们在调用sendfile发送数据的期间,如果另外一个进程将文件截断的话,会发生什么事情?如果进程没有为SIGBUS注册任何信号处理函数的话,sendfile系统调用返回被信号中断前已发送的字节数,并将全局变量errno置为成功。

 

然而,如果在调用sendfile之前,从内核获得了文件租约,那么类似的,在sendfile调用返回前会收到RT_SIGNAL_LEASE。

 

到此为止,我们已经能够避免内核进行多次复制,然而我们还存在一分多余的副本。这份副本也可以消除吗?当然,在硬件提供的一些帮助下是可以的。为了消除内核产生的素有数据冗余,需要网络适配器支持聚合操作特性。该特性意味着待发送的数据不要求存放在地址连续的内存空间中;相反,可以是分散在各个内存位置。在内核版本2.4中,socket缓冲区描述符结构发生了改动,以适应聚合操作的要求——这就是Linux中所谓的"零拷贝“。这种方式不仅减少了多个上下文切换,而且消除了数据冗余。从用户层应用程序的角度来开,没有发生任何改动,所有代码仍然是类似下面的形式:

 

sendfile(socket, file, len);

 

为了更好的理解所涉及的操作,请看图4

Figure 4. Hardware that supports gather can assemble data from multiple memory locations, eliminating another copy.

 

 

 

步骤一:sendfile系统调用导致文件内容通过DMA模块被复制到内核缓冲区中。

 

步骤二:数据并未被复制到socket关联的缓冲区内。取而代之的是,只有记录数据位置和长度的描述符被加入到socket缓冲区中。DMA模块将数据直接从内核缓冲区传递给协议引擎,从而消除了遗留的最后一次复制。

 

由于数据实际上仍然由磁盘复制到内存,再由内存复制到发送设备,有人可能会声称这并不是真正的"零拷贝"。然而,从操作系统的角度来看,这就是"零拷贝",因为内核空间内不存在冗余数据。应用"零拷贝"特性,出了避免复制之外,还能获得其他性能优势,例如更少的上下文切换,更少的CPU cache污染以及没有CPU必要计算校验和。

 

现在我们明白了什么是"零拷贝",让我们将理论付诸实践,编写一些代码。你可以从www.xalien.org/articles/source/sfl-src.tgz处下载完整的源码。执行"tar -zxvf sfl-src.tgz"将源码解压。运行make命令,编译源码,并创建随机数据文件data.bin

 

从头文件开始介绍代码:

 

/* sfl.c sendfile example program

Dragan Stancevic <

header name                 function / variable

-------------------------------------------------*/

#include <stdio.h>          /* printf, perror */

#include <fcntl.h>          /* open */

#include <unistd.h>         /* close */

#include <errno.h>          /* errno */

#include <string.h>         /* memset */

#include <sys/socket.h>     /* socket */

#include <netinet/in.h>     /* sockaddr_in */

#include <sys/sendfile.h>   /* sendfile */

#include <arpa/inet.h>      /* inet_addr */

#define BUFF_SIZE (10*1024) /* size of the tmp

                               buffer */

 

除了基本socket操作所需要的 <sys/socket.h> 和<netinet/in.h>头文件外,我们还需要包含sendfile系统调用的原型定义,这可以在<sys/sendfile.h>头文件中找到。

 

服务器标志:

 

/* are we sending or receiving */

if(argv[1][0] == 's') is_server++;

/* open descriptors */

sd = socket(PF_INET, SOCK_STREAM, 0);

if(is_server) fd = open("data.bin", O_RDONLY);

 

 

该程序既能以服务端/发送方,也能以客户端/接收方的身份运行。我们需要检查命令行参数中的一项,然后相应的设置is_server标志。程序中大开了一个地址族为PF_INET的流套接字;作为服务端运行时需要向客户发送数据,因此要打开某个数据文件。由于程序中是用sendfile系统调用来发送数据,因此不需要读取文件内容并存储在程序的缓冲区内。

 

接下来是服务器地址:

 

/* clear the memory */

memset(&sa, 0, sizeof(struct sockaddr_in));

/* initialize structure */

sa.sin_family = PF_INET;

sa.sin_port = htons(1033);

sa.sin_addr.s_addr = inet_addr(argv[2]);

 

将服务端地址结构清零后设置协议族、端口和IP地址。服务端的IP地址作为命令行参数传递给程序。端口号硬编码为1033,选择该端口是因为它在要求root权限的端口范围之上。

 

下面是服务端的分支代码:

 

if(is_server){

    int client; /* new client socket */

    printf("Server binding to [%s]/n", argv[2]);

    if(bind(sd, (struct sockaddr *)&sa,

                      sizeof(sa)) < 0){

        perror("bind");

        exit(errno);

    }

 

作为服务端,需要为socket描述符分配一个地址,这是通过系统调用bind完成的,它将服务器地址(sa)分配给socket描述符(sd).

 

if(listen(sd,1) < 0){

    perror("listen");

    exit(errno);

}

 

由于使用流套接字,必须对内核声明接受外来连接请求的意愿,并设置连接队列的尺寸。此处将队列长度设为1,但是通常会将该值设的高一些,用于接受已建立的连接。在老版本的内核中,该队列被用于阻止SYN flood攻击。由于listen系统调用之改为设定已建立连接的数量,该特性已被listen调用遗弃。内核参数tcp_max_syn_backlog承担了保护系统不受SYN flood攻击的功能。

 

if((client = accept(sd, NULL, NULL)) < 0){

    perror("accept");

    exit(errno);

}

 

accept系统调用从待处理的已连接队列中选取第一个连接请求,为之建立一个新的socket。accept调用的返回值是新建立连接的描述符;新的socket可以用于read、write和poll/select系统调用。

 

if((cnt = sendfile(client,fd,&off,

                          BUFF_SIZE)) < 0){

    perror("sendfile");

    exit(errno);

}

printf("Server sent %d bytes./n", cnt);

close(client);

 

在客户socket描述符上已经建立好连接,因此可以开始将数据传输至远端系统——这时通过调用sendfile系统调用来完成。该调用在Linux中的原型为如下形式:

 

extern ssize_t

sendfile (int __out_fd, int __in_fd, off_t *offset,

          size_t __count) __THROW;

 

前两个参数为文件描述符,第三个参数表示sendfile开始传输数据的偏移量。第四个参数是打算传输的字节数。为了sendfile可以使用"零拷贝“特性,网卡需要支持聚合操作,此外还应具备校验和计算能力。如果你的NIC不具备这些特性,仍可以是用sendfile来发送数据,区别是内核在传输前会将所有缓冲区的内容合并。

 

移植性问题

 

sendfile系统调用的问题之一,总体上来看,是缺少标准化的实现,这与open系统调用类些。sendfile在Linux、Solaris或HP-UX中的实现有很大的不同。这给希望在网络传输代码中利用"零拷贝"的开发者带来了问题。

 

这些实现差异中的一点在于Linux提供的sendfile,是定义为用于两个文件描述符之间和文件到socket之间的传输接口。另一方面,HP-UX和Solaris中,sendfile只能用于文件到socket的传输。

 

第二点差异,是Linux没有实现向量化传输。Solaris和HP-UX 中的sendfile系统调用包含额外的参数,用于消除为待传输数据添加头部的开销。

 

展望

 

Linux中“零拷贝”的实现还远未结束,并很可能在不久的未来发生变化。更多的功能将会被添加,例如,现在的sendfile不支持向量化传输,而诸如Samba和Apache这样的服务器不得不是用TCP_COKR标志来执行多个sendfile调用。该标志告知系统还有数据要在下一个sendfile调用中到达。TCP_CORK和TCP_NODELAY不兼容,后者在我们希望为数据添加头部时使用。这也正是一个完美的例子,用于说明支持向量化的sendfile将在那些情况下,消除目前实现所强制产生的多个sendfile调用和延迟。

 

当前sendfile一个相当令人不愉快的限制是它无法用户传输大于2GB的文件。如此尺寸大小的文件,在今天并非十分罕见,不得不复制数据是十分令人失望的。由于这种情况下sendfile和mmap都是不可用的,在未来内核版本中提供sendfile64,将会提供很大的帮助。

 

 

结论

 

尽管有一些缺点,"零拷贝"sendfile是一个很有用的特性。我希望读者认为本文提供了足够的信息以开始在程序中使用sendfile。如果你对这个主题有更深层次的兴趣,敬请期待我的第二篇文章——"Zero Copy II: Kernel Perspective",在其中将更深一步的讲述"零拷贝"的内核内部实现。

 
java与zero-copy java与零拷贝技术原理的一篇英文文档,图文并茂的讲解了zero 技术与java中的实现。一篇短文,值得一看 立即下载

相关推荐

Linux I/O 原理和 Zero-copy 技术全面揭秘

两万字长文从虚拟内存、I/O 缓冲区,用户态&内核态以及 I/O 模式等等知识点全面而又详尽地剖析 Linux 系统的 I/O 底层原理,分析了 Linux 传统的 I/O 模式的弊端,进而引入 Linux Zero-copy 零拷贝技术的介绍和原理解析,将零拷贝技术和传统的 I/O 模式进行区分和对比,帮助读者理解 Linux 内核对 I/O 模块的优化改进思路。 全网最深度和详尽的 Linux I/O 及零拷贝技术的解析文章。

零拷贝(Zero Copy)技术

零拷贝技术简述

qq_35630121的博客 3307

从FedAvg到实战:手把手教你用PyTorch复现联邦学习经典论文实验(MNIST/CIFAR-10)

本文详细介绍了如何使用PyTorch复现联邦学习经典算法FedAvg在MNIST和CIFAR-10数据集上的实验。从环境搭建、数据非IID划分到模型实现和参数聚合,手把手教你掌握联邦学习的核心技术与实战技巧,帮助开发者和研究人员快速实现隐私保护的分布式机器学习方案。

weixin_29053695的博客 253

零拷贝技术第一篇:综述

零拷贝(zero copy)在一些语境下指代的意思有所不同,本文讲的零拷贝就是大家常说的,通过这个技术让CPU释放出来不去执行内存中数据拷贝的功能,或者避免不必要的拷贝,所以说零拷贝不是没有数据的拷贝(复制),而是广义上讲的减少和避免不必要的数据拷贝,可以用来节省CPU使用和内带宽等,比如通过网络高速传输文件、实现网络proxy等等,零拷技术可以极大的提高程序的性能。本文总结零拷贝的各种技术,下一...

Go中国 1221

MPC-CBF 控制原理详解

假设系统满足如下离散时间动力学模型xt1fxtutxt∈Xut∈Uxt1​fxt​ut​xt​∈Xut​∈Uxtx_txt​:状态变量,定义域为可行状态集X⊆RnX⊆Rnutu_tut​:控制输入,定义域为控制约束集U⊆RmU⊆Rm系统需满足安全约束,由如下控制障碍函数(CBF)hX→RhX→RCx∈X∣hx≥0C:=x∈X∣hx≥。

m0_54691290的博客 1179

MDM主数据清洗和编码集成说明

绝大多数的企业业务系统是伴随业务发展而建设的,但随着业务发展单一系统难以支撑企业业务闭环。MDM主数据管理平台可以满足企业数据治理的需求,本文针对主数据清洗和编码集成进行梳理。...

数通畅联 3318

zero copy零拷贝学习

可以看到, 整个数据传输的过程,CPU 不再参与数据搬运的工作,而是全程由 DMA 完成,但是 CPU 在这个过程中也是必不可少的,因为传输什么数据,从哪里传输到哪里,都需要 CPU 来告诉 DMA 控制器。首先,期间共发生了 4 次用户态与内核态的上下文切换,因为发生了两次系统调用,一次是 read() ,一次是 write(),每次系统调用都得先从用户态切换到内核态,等内核完成任务后,再从内核态切换回用户态。如果采用 fbufs 这种方法,需要交换的是包含数据的缓冲区,这样就消除了多余的拷贝操作。

wade1010的专栏 346

MPU6050模块DIY翻车实录:ID能读但数据全为零?原来是这个10uF电容惹的祸

本文详细记录了MPU6050模块调试过程中遇到的ID能读但数据全为零的问题排查过程。通过对比不同参考设计,发现CPOUT引脚10uF电容选择不当是导致数据异常的根源,更换为官方推荐的2.2nF电容后问题解决。文章为硬件开发者提供了宝贵的电路设计经验。

weixin_29158047的博客 319

深入彻底理解零拷贝技术

零拷贝(Zero-Copy)技术是一个思想,是一种 I/O 操作优化技术,可以快速高效地将数据在文件系统移动和网络接口之间传输数据,而不需要将其从内核空间复制到用户空间。但零拷贝并不代表一次数据复制都没有,而是尽最大可能的减少。实际上Zero-Copy中有一项核心技术即DMA,在IO操作中扮演十分重要的角色,具体原理不是本文范围,可自行查阅资料。 先看一个常规的IO操作,需要从磁盘中读取数据,通过网络传输出去。补充一个技术点💡 DMA技术是Direct Memory Access的缩写。..........

技术百宝箱 1060

【processing】创意编程

首先接到这个作业的时候,我是很崩溃的,我是真的不会画画QAQ,还画自己,这也太难了,于是我决定!还是祸害我爱豆吧!于是我从微博太太那里找了个图临摹 下面是太太的图 先给太太道歉!都是为了作业! 然后我画出来是这样子的 还可以!!!没有特别丑!(虽然也不是特别像吧) 但是画这个真是画死我了,下面贴上代码吧,没啥特殊的就是各种贝塞尔曲线各种圆各种线 //face stroke(70,27,11...

qq_25700571的博客 1267

零基础玩转华为AP 4050DN-HD:FAT模式家庭无线网络配置实战

本文为零基础用户提供华为AP 4050DN-HD从FIT模式转换为FAT模式的完整实战教程。详细介绍了固件升级、模式转换以及配置家庭无线网络(包括路由、DHCP、Wi-Fi和NAT)的每一步操作,帮助用户将企业级瘦AP改造为高性能家庭胖AP,打造稳定可靠的家庭网络环境。

weixin_29196613的博客 630

Kafka Zero-Copy 使用分析

Kafka的高效读写是有Zore-copy技术实现的,那么Zore-copy是如何作用于Kafka呢?关于Zore-copy技在此不再赘述。 Kafka在什么场景下用了这个技术 Zero-Copy 是如何被调用,并且发挥作用的。Kafka在什么场景下使用该技术 答案是:消息消费的时候 包括外部Consumer以及Follower 从partiton Leader同步数据,都是如

Kuzury 1137

LIS3DHTR三轴加速度计Arduino驱动与嵌入式集成指南

加速度计是嵌入式系统中实现运动感知、姿态解算和振动分析的核心传感器。其工作原理基于MEMS微机械结构在惯性力作用下的电容变化,经片内ADC转换为数字信号;I²C接口因其硬件资源占用少、布线简洁,成为低功耗物联网节点的主流通信方式。技术价值体现在高分辨率(12位)、多量程(±2g~±16g)与低功耗(待机电流仅2µA)的平衡,支撑电池供电设备长期运行。典型应用场景包括可穿戴设备的姿态识别、工业预测性维护中的振动监测,以及智能硬件的敲击/跌落检测。本文围绕LIS3DHTR芯片及其Grove模块,详解Arduin

weixin_42584758的博客 594

什么是Zero-copy零拷贝

零拷贝 zero copy的含义以及发展过程。

jinking01的专栏 510

LeRobot 官方论文:一个用于端到端机器人学习的开源库

本文介绍了一个名为LeRobot的开源库,旨在解决机器人学习领域的碎片化问题。该库提供了端到端的技术栈,包括统一的机器人中间件API、标准化的数据集格式(LeRobotDataset)、优化的推理栈以及多种最先进机器人学习算法的实现。LeRobot支持多种低成本开源机器人平台(如SO-10X、ALOHA-2等),通过共享中间件实现便捷的遥操作和数据收集。其数据集格式已广泛应用于社区,截至2025年9月已有16,000多个数据集公开共享。该库还支持流式处理大规模数据,降低了研究门槛。在模型方面,LeRobot

2506_90492529的博客 905

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

linux的zero copy

许多web应用都会向用户提供大量的静态内容,这意味着有很多data从硬盘读出之后,会原封不动的通过socket传输给用户。这种操作看起来可能不会怎么消耗CPU,但是实际上它是低效的:kernal把数据从disk读出来,然后把它传输给user级的application,然后application再次把同样的内容再传回给处于kernal级的socket。这种场景下,application实际上只是作为

cglThk的专栏 776

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux Zero Copy技术

Linux Zero Copy 技术通过减少数据在用户空间和内核空间之间的拷贝次数,显著提高了 I/O 操作的效率。通过sendfilesplicevmsplice()tee()、TCP Zero Copy 和io_uring等多种实现方式,可以根据不同的应用场景选择合适的零拷贝技术。在实际应用中,Kafka 和 Nginx 等项目已经成功地利用 Zero Copy 技术提升了性能。然而,在处理大文件时,需要注意 PageCache 的限制,并选择合适的 I/O 模式以避免性能瓶颈。

jwybobo2007的博客 1023

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Zero-Copy && mmap

转载:http://www.linuxjournal.com/article/6345?page=0,0 本地文件网络传输过程   传统的文件读写过程,涉及到系统调用read、write,产生了4次上下文切换、2次CPU拷贝和2次DMA拷贝,CPU拷贝会占消耗CPU资源,成本高,而DMA拷贝是驱动进行的,对CPU的消耗很小,具体过程如下: Step one: the read system...

yamaxifeng_132的专栏 488

Zero-copy

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34411563的博客 103

zero-copy 原理

1. 传统模型 要想了解zero-copy 我们需要知道该技术的应用场景,网络传输中一个基本的场景是:通过网络传输一个文件。代码如下 read(file,tmp_buf,len); write(socket,tmp_buf,len); 在这个场景中,至少出现4次数据拷贝和3次的内核态和用户态的切换。看下图,上面的部分显示的是上下文切换的过程,下部分展示的是数据拷贝的过程。 第一步: 读取文件的...

qzqanzc的博客 498

Zero Copy 简介

许多web应用都会向用户提供大量的静态内容,这意味着有很多data从硬盘读出之后,会原封不动的通过socket传输给用户。这种操作看起来可能不会怎么消耗CPU,但是实际上它是低效的:kernal把数据从disk读出来,然后把它传输给user级的application,然后application再次把同样的内容再传回给处于kernal级的socket。这种场景下,application实际上只是作为

lyasua的专栏 558

Zero Copy 零拷贝 简介

 许多web应用都会向用户提供大量的静态内容,这意味着有很多data从硬盘读出之后,会原封不动的通过socket传输给用户。这种操作看起来可能不会怎么消耗CPU,但是实际上它是低效的:kernal把数据从disk读出来,然后把它传输给user级的application,然后application再次把同样的内容再传回给处于kernal级的socket。这种场景下,application实际上

Kinector的专栏 2662

zero copy java_Netty 之 Zero-copy 的实现(下)

上一篇说到了 CompositeByteBuf ,这一篇接着上篇的讲下去。FileRegion让我们先看一个Netty官方的example// netty-netty-4.1.16.Final\example\src\main\java\io\netty\example\file\FileServerHandler.javapublic void channelRead0(ChannelHandl...

weixin_33549415的博客 184

zero copy 为什么快

转自 :http://blog.youkuaiyun.com/jiangbo_hit/article/details/6146502 一、典型IO调用的问题 一个典型的web服务器传送静态文件(如CSS,JS,图片等)的过程如下: read(file, tmp_buf, len); write(socket, tmp_buf, len); 首先调用read将文件从磁盘读取到tmp_buf,然

chenfenggang的专栏 641

什么是Zero-Copy?

1.概述 考虑这样一种常用的情形: 2.详述 3.进阶

chenjian723122704的专栏 436

Linux IO和Zero Copy总结

前言 最近工作中一个系统要基于cannal订阅binlog数据,然后本地消费,但是发现IO居高不下,通常情况达到150%以上,顺着这个问题阅读了canal中关于网络数据处理的源码,发现性能并不是好,后面不得不切换到改用kafka消费,而kafka作为一个高性能消息处理中间件能够实现海量消息处理的一个因素是因为Zero Copy,借此机会重新总结了下Linux下IO的一些知识。 几种IO介绍 ...

Kubernetes云计算的专栏 752
上一篇: linux下的多线程编程
下一篇: linux驱动中的write函数
zhoujunyi
博客等级 码龄22年 147粉丝 104原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值