零拷贝详解

定义

零拷贝就是一种避免 CPU 将数据从一块存储拷贝到另外一块存储(比如从网络设备到用户程序空间)的技术。通过减少数据拷贝次数,减少系统调用和上下文切换,实现CPU的零参与,彻底消除 CPU在这方面的负载。

背景

高速网络的网络链接能力与 CPU 的处理能力接近,甚至会超过 CPU 的处理能力。这就产生了性能瓶颈,限制了通讯速率。举例来说,一个 1 GHz 的处理器可以对 1Gbit/s 的网络链接进行传统的数据拷贝操作,但是网络链接的处理能力比 CPU 的处理能力的增长要快得多。如果是 10 Gbit/s 的网络,零拷贝技术就变得非常重要了。

传统IO方式

4次上下文切换+4次数据拷贝
在这里插入图片描述

读数据过程
应用程序要读取磁盘数据,调用read()函数从而实现用户态切换内核态,这是第1次状态切换;
DMA控制器将数据从磁盘缓冲区拷贝到内核缓冲区,这是第1次DMA拷贝;
CPU将数据从内核缓冲区复制到用户缓冲区,这是第1次CPU拷贝;
CPU完成拷贝之后,read()函数返回实现用户态切换用户态,这是第2次状态切换;
写数据过程
应用程序要向网卡写数据,调用write()函数实现用户态切换内核态,这是第1次切换;
CPU将用户缓冲区数据拷贝到内核缓冲区,这是第1次CPU拷贝;
DMA控制器将数据从内核缓冲区复制到socket缓冲区,这是第1次DMA拷贝;
完成拷贝之后,write()函数返回实现内核态切换用户态,这是第2次切换;
综上所述
读过程涉及2次空间切换、1次DMA拷贝、1次CPU拷贝; 写过程涉及2次空间切换、1次DMA拷贝、1次CPU拷贝。所以共4次切换+4次拷贝。

零拷贝技术

mmap+write、sendfile(Linux 内核2.1版本)、sendfile+DMA Scatter/Gather(分散/收集)(Linux2.4内核版本)、splice等。
在这里插入图片描述

mmap+write

减少一次CPU拷贝,即3次拷贝+4次状态切换

优缺点:mmap对大文件传输有一定优势,但是小文件可能出现碎片,并且在多个进程同时操作文件时可能产生引发coredump的signal。

mmap()函数的用法:
char *fileContent = static_cast<char *>(mmap(nullptr, fileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
入参分别是:起始地址、映射的长度、保护模式(PROT_READ、PROT_WRITE 等)、映射标志(MAP_SHARED 等)、文件描述符和偏移量。
 1. nullptr: 表示指定映射的内存地址,这里传入 nullptr,表示让系统自动选择一个合适的空闲地址用于内存映射。
 2. fileStat.st_size: 表示映射的内存区域的大小,即文件的大小,假设在前面已经通过 fstat() 函数获取文件的状态信息,其中 st_size 成员表示文件的大小。
 3. PROT_READ | PROT_WRITE: 表示映射区域的访问权限,PROT_READ 表示区域可被读取,PROT_WRITE表示区域可被写入。
 4. MAP_SHARED: 表示映射区域是共享的,即多个进程可以共享同一个映射区域对文件进行读写操作。
 5. fd: 表示要映射到内存的文件的文件描述符,通过 open() 函数打开文件获取的文件描述符。
 6. 0: 表示映射的起始位置,这里使用 0 表示从文件的起始处进行映射。

另外,文件发送结束时,使用munmap()系统调用删除指定地址范围的映射。

sendfile(Linux 内核2.1版本)

少了2次状态切换(刚开调用sendfile()函数进入内核态,最后将数据从socket缓冲区拷贝到网卡后切换回用户态)。过程见网图:

在这里插入图片描述
所以总共是3次拷贝+2次状态切换。

局限:由于数据不经过用户缓冲区,因此该数据无法被修改

splice

可以在内核缓冲区和socket缓冲区之间建立管道来传输数据,避免了两者之间的 CPU 拷贝操作。
在这里插入图片描述

局限:两个文件描述符参数中有一个必须是管道设备。

sendfile+DMA Scatter/Gather(分散/收集)(Linux2.4内核版本)

它将读缓冲区中的数据描述信息–内存地址和偏移量记录到socket缓冲区,由 DMA 根据这些将数据从读缓冲区拷贝到网卡,相比之前版本减少了一次CPU拷贝的过程.
在这里插入图片描述
整个过程发生了2次用户态和内核态的上下文切换和2次拷贝,其中更重要的是完全没有CPU拷贝(真正的零拷贝)。

局限:DMA gather和sendfile一样数据对用户空间不可见,而且需要硬件支持,同时输入文件描述符只能是文件(不能是socket和管道,他们也有fd)。

此外,DPDKRDMA也实现了零拷贝。


原文:从原理到实践:完全掌握零拷贝技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值