零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(下)

简介: 本章节主要讨论了如何通过零拷贝技术来优化文件传输的性能。零拷贝技术主要通过减少用户态和内核态之间的上下文切换次数和数据拷贝次数来提高性能。具体来说,介绍了两种实现零拷贝的方式:mmap + write和sendfile。使用mmap + write可以减少一次数据拷贝过程,而使用sendfile系统调用可以进一步减少系统调用和数据拷贝次数。此外,还介绍了如果网卡支持SG-DMA技术,可以通过DMA将数据直接拷贝到网卡缓冲区,实现真正的零拷贝。通过这些优化方法,可以显著提高文件传输的性能。

前章回顾

在前一章节中,我们了解了DMA技术在文件传输中的重要性,并简要介绍了零拷贝技术。为了提高文件传输的性能,我们需要减少用户态与内核态之间的上下文切换次数以及内存拷贝次数。本章将深入探讨零拷贝技术的优化方法,让我们一起走进零拷贝的优化之路!

如何优化文件传输的性能?

当我们意识到有问题需要进行优化时,我们可以逐个解决问题,例如先减少用户态和内核态的上下文切换次数。

我们知道上下文切换是因为用户空间没有权限操作磁盘或网卡,而只能在虚拟空间上进行。相比之下,内核拥有最高权限,因此操作设备的任务都需要操作系统内核完成。为此,我们需要使用操作系统提供的系统调用函数来通过内核完成这些任务。如果对此还不清楚的小伙伴,可以查看之前章节中单独讲解的内容。

一次系统调用必然会发生两次上下文切换:首先从用户态切换到内核态,当内核执行完任务后,再切换回用户态由进程代码继续执行。

因此,要减少上下文切换的次数,就需要减少系统调用的次数。

另外,我们还可以减少数据拷贝的次数。在之前的分析中,我们发现操作会进行四次数据拷贝,包括两次CPU拷贝和两次DMA控制器数据拷贝。然而,在文件传输过程中,我们实际上并没有对文件进行任何操作,只是将磁盘文件传输给网卡。CPU数据拷贝的次数是由于上下文切换导致CPU在用户态和内核态之间来回复制数据,这是没有必要的。此外,用户缓冲区在整个传输过程中也是没有必要存在的。

如何实现零拷贝

零拷贝技术实现的方式通常有 2 种:

  1. mmap + write
  2. sendfile

让我们来探讨一下如何通过两种方式实现零拷贝技术,从而减少上下文切换和数据拷贝的次数。

mmap(共享缓冲区) + write

首先是使用 mmap + write 的方式。在之前的讨论中,我们了解到在使用 read() 系统调用时,会发生将内核缓冲区的数据拷贝到用户缓冲区的过程。为了减少这一步的开销,可以使用 mmap() 替换 read() 系统调用函数。

我们之前在讨论进程间如何通信时,我们有提到过共享缓冲区,即将内核态的一部分内存空间映射到应用程序所使用的虚拟空间上。如图所示:

image

而我们此时并不需要多个进程通信,如果只需要将物理内存映射给需要文件传输的进程,情况就会变得稍有不同。那么就可以演化成下面的这种方式,如图所示:

image

具体过程如下:

  1. 应用程序调用 mmap() 函数后,DMA会将磁盘数据拷贝到内核态的缓存区上,然后应用程序与操作系统共享这个缓冲区。
  2. 应用程序调用 write(),操作系统直接将内核态中的缓冲区数据拷贝到 socket 缓冲区,此时只在内核态进行操作,不会产生用户态和内核态切换,数据搬运过程由CPU完成。
  3. 最后,将内核的 socket 缓冲区数据拷贝到网卡中的数据缓冲区,这一步由DMA控制器操作。

我们可以得知,通过使用 mmap() 替代 read(),可以减少一次数据拷贝的过程。然而,这仍然不是最理想的零拷贝方式,因为仍然需要通过 CPU 将内核缓冲区的数据拷贝到 socket 缓冲区,且仍然需要进行 4 次上下文切换,因为系统调用仍然发生了两次。

接下来,我们来看第二种实现零拷贝的方式 - sendfile。

sendfile

在 Linux 内核版本 2.1 中,引入了一个名为sendfile()的系统调用函数,它提供了一种更高效的文件发送方法。sendfile()函数的使用方式如下:

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

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

sendfile()函数具有以下优点:

首先,它可以代替之前需要使用read()和write()两个系统调用的操作,从而减少了一次系统调用的开销。尽管sendfile()函数本身仍然需要进行系统调用,但仍然能够减少了2次上下文切换的开销。

其次,该系统调用可以直接将内核缓冲区中的数据复制到套接字缓冲区中,而无需再复制到用户态。这样一来,只需要进行2次上下文切换和3次数据拷贝。下图展示了这一过程的流程:

image

然而,这个过程仍然不能被称为真正的零拷贝技术。如果我们的网卡支持SG-DMA(散射-聚集直接内存访问)技术,与普通的DMA有所不同,那么我们可以进一步减少通过CPU将内核缓冲区中的数据拷贝到套接字缓冲区的过程。

你可以在你的Linux系统上使用以下命令来查看网卡是否支持散射-聚集特性::

$ ethtool -k eth0 | grep scatter-gather
scatter-gather: on

因此,从Linux内核2.4版本开始,在网卡支持SG-DMA技术的情况下,sendfile()系统调用的过程发生了一些变化,具体过程如下:

第一步,通过DMA将磁盘上的数据拷贝到内核缓冲区中;

第二步:内核缓冲区只需要将描述符和数据长度发送给套接字缓冲区,然后将直接通过SG-DMA将内核缓冲区中的数据拷贝到网卡的缓冲区中,这个过程不再需要从操作系统的内核缓冲区中拷贝到套接字缓冲区,从而减少了一次数据拷贝的过程。

因此,在这个过程中,只进行了两次数据拷贝,如下图所示:

image

这就是所谓的零拷贝(Zero-copy)技术,因为我们没有在内存层面进行数据拷贝,也就是说在整个过程中没有使用CPU来传输数据,而是完全依靠DMA来进行数据传输。

相比传统的文件传输方式,零拷贝技术可以减少2次上下文切换和数据拷贝的次数,只需要进行2次上下文切换和数据拷贝,就能完成文件的传输。而且这2次数据拷贝过程都不需要通过CPU,而是由DMA来进行数据传输。

因此,总体来看,零拷贝技术可以将文件传输的性能提升至少一倍以上。值得一提的是,在讲解零拷贝技术时,并没有提到网络协议是在哪个步骤中封装的。大家也应该知道,在内核中完成了网络协议的封装,而不是直接从缓冲区中取出数据并发送给网卡就结束了。

总结

本章主要介绍了零拷贝技术在文件传输中的优化方法。首先,通过减少用户态和内核态之间的上下文切换次数和数据拷贝次数来优化文件传输的性能。其次,介绍了两种实现零拷贝的方式:mmap + write和sendfile。通过使用mmap + write,可以将内核缓冲区的数据直接拷贝到socket缓冲区,减少一次数据拷贝过程。而使用sendfile系统调用,则可以进一步减少系统调用和数据拷贝次数。若网卡支持SG-DMA技术,还可以通过DMA将内核缓冲区的数据直接拷贝到网卡缓冲区,实现真正的零拷贝。

相关文章
|
2天前
|
存储 安全 算法
网络安全与信息安全:防御前线的关键技术与意识觉醒
【5月更文挑战第12天】在数字化浪潮不断推进的今天,网络安全与信息安全已成为维护社会稳定、保障个人隐私和商业秘密的重要屏障。本文深入探讨了网络安全漏洞的形成机理及其对信息系统的潜在威胁,分析了加密技术在数据保护中的应用及发展,并强调了提升全社会网络安全意识的必要性。通过综合研究,旨在为读者提供一套全面的网络安全知识框架,以及实用的防护策略。
9 2
|
4天前
|
存储 安全 物联网
网络安全与信息安全:防御前线的技术与意识
【5月更文挑战第9天】 在数字化时代,网络安全和信息安全已成为维护个人隐私、企业数据和国家安全的基石。本文将深入探讨网络安全漏洞的概念、加密技术的重要性以及提升安全意识的必要性。通过对这些关键领域的分析,我们将了解如何构建一个更加坚固的信息安全防线,并掌握保护信息不受未授权访问、泄露或破坏的策略和技术。
|
6天前
|
负载均衡 网络协议
虚拟网络技术:bond技术
虚拟网络技术:bond技术
8 0
|
7天前
|
运维 安全 网络协议
即时通讯安全篇(十四):网络端口的安全防护技术实践
网络端口因其数量庞大、端口开放和关闭的影响评估难度大,业务影响程度高、以及异常识别技术复杂度高等特点给网络端口安全防护带来了一定的挑战,如何对端口风险进行有效治理几乎是每个企业安全团队在攻击面管理工作中持续探索的重点项。
19 0
|
8天前
|
安全 物联网 网络安全
网络安全与信息安全:防御前线的关键技术与策略
【5月更文挑战第6天】在数字化时代,网络安全与信息安全已成为保护个人隐私、企业资产和国家安全不可或缺的一环。本文深入探讨了网络安全漏洞的概念、加密技术的进展以及提升安全意识的重要性。通过分析当前网络环境中存在的风险和挑战,文章提出了一系列创新的防御措施和最佳实践,旨在帮助读者构建一个更加安全的网络环境。
|
10天前
|
SQL 安全 算法
网络安全与信息安全:防御前线的技术与意识
【5月更文挑战第4天】在数字化时代,网络安全和信息安全已成为维护网络环境稳定的关键。本文深入探讨了网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性,旨在为读者提供全面的安全防护策略。通过对常见安全威胁的分析,我们展示了如何运用现代加密技术和安全机制来保护数据和隐私。同时,文章强调了培养个人和组织的安全意识对于构建安全防线的核心作用。
17 0
|
10天前
|
存储 安全 网络安全
网络安全与信息安全:防御前线的技术与意识
【5月更文挑战第3天】 在数字化时代,网络安全和信息安全已成为维护社会稳定、保护个人隐私和企业资产的重要领域。本文深入探讨了网络安全漏洞的成因与影响,加密技术的最新发展以及提升安全意识的必要性。通过对现有威胁的分析,我们强调了构建多层次防御策略的重要性,并提出了相应的技术解决方案和管理措施。
|
12天前
|
存储 SQL 安全
网络安全与信息安全:防御前线的关键技术与策略
【5月更文挑战第2天】 在数字化时代,数据成为了新的货币,而网络安全则是保护这些宝贵资产不受威胁的盾牌。本文将深入探讨网络安全漏洞的本质,分析加密技术如何成为防御体系的核心,并强调提升个人和企业的安全意识在构建坚固防线中的重要性。通过技术性解析和实践策略的分享,旨在为读者提供一套综合性的网络与信息安全解决方案。
|
13天前
|
安全 网络安全
网络安全攻防实战演练:技术探索与实践
【5月更文挑战第1天】网络安全攻防实战演练,通过模拟攻击与防御,提升组织应对网络安全威胁的能力。演练包括准备、攻击、防御和总结四个阶段,涉及环境搭建、攻击技术应用、防御措施执行及后期评估。此类演练有助于检验安全防护能力,提升应急响应速度,暴露系统隐患,加强团队协作,是保障网络安全的关键实践。
|
13天前
|
机器学习/深度学习 自动驾驶 安全
基于深度学习的图像识别技术在自动驾驶系统中的应用网络安全与信息安全:防御前线的关键技术与意识
【4月更文挑战第30天】随着人工智能技术的飞速发展,深度学习已成为推动多个技术领域革新的核心力量。特别是在图像识别领域,深度学习模型已展现出超越传统算法的性能。在自动驾驶系统中,准确的图像识别是确保行车安全和高效导航的基础。本文将探讨深度学习在自动驾驶中图像识别的应用,分析关键技术挑战,并提出未来的发展方向。