偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

三分鐘掌握零拷貝的那些事

開發(fā) 前端
splice是在內核空間的緩存區(qū)和socket緩存區(qū)之間建立管道,從而避免了兩者之間的CPU拷貝操作。?splice的整個拷貝過程發(fā)生了2次用戶態(tài)和內核態(tài)的切換,2次數據的拷貝(2次DMA拷貝、0次CPU拷貝)。

零拷貝可以直觀的理解為不需要將數據從一個存儲區(qū)域拷貝到另外一個存儲區(qū)域,從而提高數據的效率。這里的零是指CPU參與整個拷貝過程的次數。下面我們來聊聊傳統的數據傳輸(write+read)和零拷貝的幾種實現方式的數據傳輸原理。

1、write+read數據傳輸的原理

在我們的Java代碼中傳輸的數據時候會用到write方法,write方法寫數據發(fā)送到網卡的過程如下圖所示:

圖片圖片

然后接收方使用read方法從網卡接收數據的流程如下圖所示:

圖片圖片

通過write+read的方式我們就可以實現數據的傳輸,但是在這兩個方法背后是需要做很多的工作,如下所示的原理圖:

圖片圖片

當我們調用read方法的時候,首先需要從用戶態(tài)切換到內核態(tài),然后通過DMA拷貝(Direct Memory Access,即直接內存訪問。DMA本質上是一塊主板上獨立的芯片,允許外設設備和內存存儲器之間直接進行IO數據傳輸,其過程不需要CPU的參與)將磁盤里面的文件拷貝到內核緩沖區(qū)上,數據拷貝到內存緩沖區(qū)之后又需要進行內核態(tài)轉化為用戶態(tài),將內核緩沖區(qū)中的數據拷貝到用戶緩沖區(qū)。這里涉及到2次的狀態(tài)切換、1次DMA拷貝、1次CPU拷貝。

文件數據拷貝到用戶緩存區(qū)之后,首先需要從用戶態(tài)切換到內核態(tài),然后通過調用write方法,此時CPU就會將用戶緩存區(qū)的文件數據拷貝到內核的socket緩存區(qū)上,最后通過DMA拷貝將數據拷貝到網卡上,當數據拷貝到網卡成功后再從內核態(tài)切換到用戶態(tài)。

傳統的文件傳輸的整個過程中,涉及到了4次用戶態(tài)與內核態(tài)的上下文切換,執(zhí)行了4次數據的拷貝(2次DMA拷貝、2次CPU拷貝)。

在文件數據傳輸的過程中,我們的目的就是將磁盤的文件發(fā)送到網卡上

圖片圖片

但是文件數據需要經過多個過程才能到達網卡,于是就研究人員提出了通過減少用戶態(tài)和內核態(tài)的轉換或者減少內存拷貝的次數的方式來提高文件拷貝的效率,這就是零拷貝技術產生的背景。

2、mmap + write

使用mmap+write方式替換原來的傳統IO方式,實質就是利用了虛擬內存。虛擬內存在現代操作系統使用很廣泛,其特性如下所示:

(a)多個虛擬內存可以指向同一個物理地址。

(b)虛擬內存空間可以遠遠大于物理內存空間。

mmap正是利用第一條特性,將內核空間和用戶空間的虛擬地址映射到同一個物理地址,這樣在IO操作時就不需要來回復制了,如下所示的虛擬內存示意圖:

圖片圖片

mmap + write實現的零拷貝的流程圖如下所示:

圖片圖片

當調用mmap方法的時候,首先從用戶態(tài)切換到內核態(tài),然后將磁盤文件使用DMA拷貝到內核緩存區(qū),由于內核緩沖區(qū)與用戶緩沖區(qū)已經完成了映射(虛擬內存),所以這個時候就不需要將數據從內核緩沖區(qū)拷貝到用戶緩存區(qū),當數據拷貝到內核緩沖區(qū)之后,又要從內核態(tài)切換到用戶態(tài)。

當調用write方法的時候,進程要從用戶態(tài)切換到內核態(tài),然后進程直接操作內核緩沖區(qū)里面的數據拷貝到socket緩沖區(qū)中,拷貝到socket緩沖區(qū)完成后,再通過DMA拷貝到網卡,網上數據拷貝完成之后又要從內核態(tài)切換到用戶態(tài)。

整個過程還是存在了4次用戶態(tài)和內核態(tài)的切換,發(fā)生了3次數據的拷貝(2次DMA拷貝、1次CPU拷貝),雖然相比于傳統的文件傳輸過程少了一次CPU拷貝,數據的傳輸的效率有一定的提升。

3、sendfile

sendfile是Linux2.1版本提供的一個系統調用函數,主要是負責發(fā)送文件的。只需要調用sendfile函數就可以完成整個文件拷貝的過程,如下圖所示的流程圖:

圖片圖片

當調用sendfile的時候,首先需要從用戶態(tài)切換到內核態(tài),使用DMA拷貝將文件拷貝到內核緩存區(qū),然后將內核緩存區(qū)的數據通過CPU拷貝到socket的緩存區(qū),最后再通過DMA拷貝數據到網卡上,完成網卡數據拷貝后再從內核態(tài)切換到用戶態(tài)。

sendfile實現數據傳輸的過程存在了2次用戶態(tài)和內核態(tài)的切換,發(fā)生了3次數據的拷貝(2次DMA拷貝、1次CPU拷貝),相比于mmap + write的方式又提升了一些效率。

4、sendfile + SG-DMA

在Linux2.4版本中網卡支持SG-DMA技術,那么使用SG-DMA可以進一步的優(yōu)化零拷貝的過程,如下所示的流程圖:

圖片圖片

當調用sendfile的時候,首先用戶態(tài)切換到內核態(tài),然后使用DMA拷貝將文件從磁盤拷貝到內核緩存區(qū),接下來它就會將描述符和數據長度發(fā)送到socket緩存區(qū),這樣就可以直接將數據從內核緩存區(qū)通過SG-DMA拷貝到網卡,數據拷貝到網卡上結束后再從內核態(tài)切換到用戶態(tài)。

通過SG-DMA拷貝就不需要將數據拷貝到socket緩存區(qū)再通過DMA的方式拷貝到網卡了,而是直接從內核緩存區(qū)拷貝到網卡。整個過程存在了2次用戶態(tài)和內核態(tài)的切換,發(fā)生了2次數據的拷貝(2次DMA拷貝、0次CPU拷貝)。

 send file + SG-DMA算是真正意義上實現了零拷貝技術,它整個過程都是通過DMA在系統內核完成的,數據拷貝不需要CPU參與。

5、splice

在Linux2.6.17內核版本中引入了splice系統調用方法,splice和sendfle方法不同點在于它是不需要硬件支持。如下所示的splice原理圖:

圖片圖片

splice是在內核空間的緩存區(qū)和socket緩存區(qū)之間建立管道,從而避免了兩者之間的CPU拷貝操作。splice的整個拷貝過程發(fā)生了2次用戶態(tài)和內核態(tài)的切換,2次數據的拷貝(2次DMA拷貝、0次CPU拷貝)。

總結:

(1)無論是傳統的IO方式還是零拷貝技術,2次DMA拷貝是必備的(DMA都是依賴硬件完成的),零拷貝只是減少CPU拷貝與上下文的切換(用戶態(tài)和內核態(tài)的切換)。

(2)零拷貝的實現有mmap+write、sendfile、sendfile + SG-DMA、splice等方式。

(3)不是所有的操作系統都支持零拷貝技術,目前只有在使用NIO和 Epoll數據傳輸時才可使用。

(4)RocketMQ和Kafka都使用到了零拷貝的技術。其中,RocketMQ中生產者發(fā)送數據、消費者讀取數據都是使用mmap+write方式;而Kafka的生產者持久化數據使用mmap+write方法,消費者讀取數據使用sendfile方式。

(5)Java的NIO中MappedByteBuffer底層使用的是mmap;FileChannel的transferTo()/transferFrom(),底層使用sendfile。

責任編輯:武曉燕 來源: 龍蝦編程
相關推薦

2022-03-26 09:06:40

ActorCSP模型

2021-12-17 07:47:37

IT風險框架

2024-05-16 11:13:16

Helm工具release

2009-11-09 12:55:43

WCF事務

2024-12-18 10:24:59

代理技術JDK動態(tài)代理

2024-12-11 12:00:00

C++拷貝

2022-02-24 10:28:23

物聯網

2024-08-30 08:50:00

2023-12-27 08:15:47

Java虛擬線程

2024-01-16 07:46:14

FutureTask接口用法

2022-02-17 09:24:11

TypeScript編程語言javaScrip

2021-04-20 13:59:37

云計算

2020-06-30 10:45:28

Web開發(fā)工具

2013-06-28 14:30:26

棱鏡計劃棱鏡棱鏡監(jiān)控項目

2025-10-27 01:35:00

2025-04-01 01:25:00

MySQLInnoDBMyISAM

2009-10-29 16:22:10

VB.NET操作MyS

2025-02-24 10:40:55

2017-11-20 10:35:36

2024-08-05 00:04:00

JSWeb應用
點贊
收藏

51CTO技術棧公眾號