Nettymmap 和 sendFile 零拷貝原理

      網友投稿 712 2025-03-31

      文章目錄


      一、 零拷貝 簡介

      二、 傳統 BIO 數據拷貝分析 ( 4拷貝 4切換 )

      三、 mmap 內存映射 ( 3拷貝 4切換 )

      四、 sendFile 函數 ( Linux 2.1 優化 ) ( 3拷貝2切換 )

      五、 sendFile 函數 ( Linux 2.4 優化 ) ( 2拷貝 2切換 )

      一、 零拷貝 簡介

      零拷貝作用 : 在網絡編程中 , 如果要進行性能優化 , 肯定要涉及到零拷貝 ,

      使用零拷貝能極大的提升數據傳輸性能 ;

      零拷貝類型 : mmap ( 內存映射 ) 和 sendFile;

      數據角度分析 : 在零拷貝機制中 , 整個數據在內存中只有一份數據 , 非零拷貝機制中 , 內核緩沖區 , 用戶緩沖區 , Socket 緩沖區 , 各有一份數據 ;

      零拷貝指的是沒有 CPU 拷貝 , 都是 DMA ( 直接內存訪問 ) 拷貝 ;

      零拷貝性能優勢 : 沒有復制數據帶來的內存開銷 , 沒有 CPU 拷貝 , 直接節省了大量 CPU 計算資源 ;

      二、 傳統 BIO 數據拷貝分析 ( 4拷貝 4切換 )

      傳統 BIO 數據拷貝代碼示例 :

      package kim.hsl.nio.zerocopy; import java.io.FileInputStream; import java.io.IOException; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.Socket; public class BIOClientDemo { public static void main(String[] args) { try { // 客戶端與服務器端連接過程忽略, 主要是分析數據拷貝過程 Socket socket = new Socket(); InetSocketAddress inetSocketAddress = new InetSocketAddress(Inet4Address.getLocalHost(), 8888); socket.connect(inetSocketAddress); // 分析下面過程中, 數據拷貝次數, 和用戶態與內核態的轉換次數 // 1. 從文件中讀取數據 FileInputStream fileInputStream = new FileInputStream("file.txt"); byte[] buffer = new byte[1024]; // 首先將硬盤中的文件, 進行 DMA 拷貝, 此處對應 read 方法, // 將文件數據從硬盤中拷貝到 內核緩沖區 ( 用戶態切換成內核態 ) // 將內核緩沖區中的數據, 通過 CPU 拷貝 方式, 拷貝到 用戶緩沖區 ( 內核態切換成用戶態 ) int readLen = fileInputStream.read(buffer); // 2. 寫出數據到服務器 // 將用戶緩沖區中的數據, 再次通過 CPU 拷貝方式, 拷貝到 Socket 緩沖區 ( 用戶態切換成內核態 ) // 再次使用 DMA 拷貝, 將 Socket 緩沖區中的數據拷貝到 協議棧 ( Protocol Engine ) 中 socket.getOutputStream().write(buffer, 0, readLen); } catch (IOException e) { e.printStackTrace(); } } }

      1

      2

      3

      4

      5

      6

      7

      【Netty】mmap 和 sendFile 零拷貝原理

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      分析上述代碼中數據拷貝次數 , 用戶態與內核態狀態切換 ;

      1 .

      fileInputStream.read(buffer)

      操作數據拷貝及狀態轉換分析 :

      ① 硬盤 ( 初始用戶態 ) -> 內核緩沖區 ( 內核態 ) : 首先將硬盤中的文件 , 進行

      DMA [ 1 ] ^{[1]} [1] 拷貝

      , 此處對應 read 方法 , 將文件數據從硬盤中拷貝到 內核緩沖區 ; ( 用戶態切換成內核態 )

      ② 內核緩沖區 ( 內核態 ) -> 用戶緩沖區 ( 用戶態 ) : 將內核緩沖區中的數據 , 通過

      CPU 拷貝

      方式 , 拷貝到 用戶緩沖區 ; ( 內核態切換成用戶態 )

      2 .

      socket.getOutputStream().write(buffer, 0, readLen)

      操作數據拷貝及狀態轉換分析 :

      ① 用戶緩沖區 ( 用戶態 ) -> Socket 緩沖區 ( 內核態 ) : 將用戶緩沖區中的數據 , 再次通過

      CPU 拷貝

      方式 , 拷貝到 Socket 緩沖區 ; ( 用戶態切換成內核態 )

      ② Socket 緩沖區 ( 內核態 ) -> 協議棧 : 再次使用

      DMA [ 1 ] ^{[1]} [1] 拷貝

      , 將 Socket 緩沖區中的數據拷貝到 協議棧 ( Protocol Engine ) 中 ;

      3 . 總結 : 上述進行了 4 4 4 次拷貝 , 3 3 3 次用戶態與內核態之間的狀態切換 , 代價很高 ;

      ① 拷貝次數分析 : 開始時數據存儲在 硬盤文件 中 ,

      直接內存拷貝 ( Direct Memory Access )

      到 內核緩沖區 ,

      CPU 拷貝

      到 用戶緩沖區 ,

      CPU 拷貝

      到 Socket 緩沖區 ,

      直接內存拷貝 ( Direct Memory Access )

      到 協議棧 ;

      硬盤文件 -> 內核緩沖區 ( 內核空間 ) -> 用戶緩沖區 ( 用戶空間 ) -> Socket 緩沖區 ( 內核空間 ) -> 協議棧

      ② 狀態改變分析 : 開始運行的是用戶應用程序 ,

      起始狀態肯定是用戶態

      , 之后將硬盤文件數據拷貝到內核緩沖區后 ,

      轉為內核態

      , 之后又拷貝到了用戶緩沖區 ,

      轉為用戶態

      ; 數據寫出到 Socket 緩沖區 ,

      又轉為內核態 ,

      最后再切換成用戶態 , 執行后續應用程序代碼邏輯 ;

      用戶態 -> 內核態 -> 用戶態 -> 內核態 -> 用戶態

      [ 1 ] [1] [1] DMA 全稱 ( Direct Memory Access ) ,

      直接內存拷貝

      ,

      該拷貝通過內存完成

      , 不涉及 CPU 參與 ;

      三、 mmap 內存映射 ( 3拷貝 4切換 )

      將硬盤中的文件映射到 內核緩沖區 , 用戶空間中的應用程序也可以訪問該 內核緩沖區 中的數據 , 使用這種機制 , 原來的 4 4 4 次數據拷貝減少到了 3 3 3 次 ,

      1 . mmap 數據拷貝過程 :

      ① 硬盤文件 -> 內核緩沖區 : 硬盤文件數據 , DMA 拷貝到 內核緩沖區 中 ,

      應用程序可以直接訪問該 內核緩沖區中的數據 ;

      ② 內核緩沖區 -> Socket 緩沖區 : 內核緩沖區 數據 , 通過 CPU 拷貝到 Socket 緩沖區 ;

      ③ Socket 緩沖區 -> 協議棧 : Socket 緩沖區 數據 , 通過 DMA 拷貝到 協議棧 ;

      硬盤文件 -> 內核緩沖區 ( 內核空間 ) -> Socket 緩沖區 ( 內核空間 ) -> 協議棧

      2 . mmap 狀態切換 : 其狀態切換還是 3 3 3 次 ,

      由初始狀態 用戶態 , 在拷貝數據到內核緩沖區時 , 切換成內核態 ,

      訪問該內核緩沖區數據時 , 又切換成用戶態 ,

      將數據拷貝到 Socket 緩沖區時 , 切換成內核態 ,

      最后再切換成用戶態 , 執行后續應用程序代碼邏輯 ;

      用戶態 -> 內核態 -> 用戶態 -> 內核態 -> 用戶態

      四、 sendFile 函數 ( Linux 2.1 優化 ) ( 3拷貝2切換 )

      sendFile 是 Linux 提供的函數 , 其實現了由

      內核緩沖區

      直接將數據拷貝到

      Socket 緩沖區

      , 該操作直接在內核空間完成 , 不經過用戶空間 , 沒有用戶態參與 , 因此

      減少了一次用戶態切換 ;

      此次優化 , 由原來的 4 4 4 次拷貝 , 3 3 3 次狀態切換 , 變成 3 3 3 次拷貝 , 2 2 2 次狀態切換 ;

      1 . sendFile 函數 數據拷貝分析 :

      ① 硬盤文件 -> 內核緩沖區 : 硬盤文件數據 , DMA 拷貝到 內核緩沖區 中 ;

      ② 內核緩沖區 -> Socket 緩沖區 : 內核緩沖區 數據 , 通過 CPU 拷貝到 Socket 緩沖區 ;

      ③ Socket 緩沖區 -> 協議棧 : Socket 緩沖區 數據 , 通過 DMA 拷貝到 協議棧 ;

      硬盤文件 -> 內核緩沖區 ( 內核空間 ) -> Socket 緩沖區 ( 內核空間 ) -> 協議棧

      2 . sendFile 函數 狀態切換分析 : 其狀態切換只有 2 2 2 次 ,

      由初始狀態 用戶態 , 在拷貝數據到內核緩沖區時 , 切換成內核態 ,

      在內核態直接將數據拷貝到 Socket 緩沖區時 , 還是處于內核狀態 ,

      之后拷貝到協議棧時 , 變成用戶狀態 ;

      用戶態 -> 內核態 -> 用戶態

      五、 sendFile 函數 ( Linux 2.4 優化 ) ( 2拷貝 2切換 )

      sendFile 是 Linux 提供的函數 , 其在 Linux 2.4 版本中 , 直接將數據從

      內核緩沖區

      拷貝到

      協議棧

      中 ;

      此次優化 , 由原來的 4 4 4 次拷貝 , 3 3 3 次狀態切換 , 變成 2 2 2 次拷貝 , 2 2 2 次狀態切換 ;

      1 . sendFile 函數 數據拷貝分析 : 全稱 DMA 拷貝 , 沒有 CPU 拷貝 ;

      ① 硬盤文件 -> 內核緩沖區 : 硬盤文件數據 , DMA 拷貝到 內核緩沖區 中 ;

      ② 內核緩沖區 -> -> 協議棧 : 通過 DMA 拷貝 , 將 內核緩沖區 中的數據直接拷貝到 協議棧 ;

      硬盤文件 -> 內核緩沖區 ( 內核空間 ) -> 協議棧

      2 . sendFile 函數 狀態切換分析 : 其狀態切換只有 2 2 2 次 ,

      由初始狀態 用戶態 , 在拷貝數據到內核緩沖區時 , 切換成內核態 ,

      在內核態直接將數據拷貝到協議棧時 , 變成用戶狀態 ;

      用戶態 -> 內核態 -> 用戶態

      3 . 少量 CPU 拷貝 : 該機制還存在少量的 CPU 拷貝 , 其 對性能的消耗忽略不計 ; 這些 CPU 拷貝操作是從

      內核緩沖區

      中將數據的長度 ( Length ) , 偏移量 ( Offset ) 拷貝到

      Socket 緩沖區

      ;

      Linux Socket編程

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:OKR的三重境界(OKR的核心)
      下一篇:請問做ppt換模板在哪里/(ppt做好了如何換模板)
      相關文章
      亚洲日本乱码一区二区在线二产线 | 亚洲成a人片毛片在线| 国产成人精品亚洲精品| 亚洲A丁香五香天堂网| 亚洲国产日韩a在线播放| 亚洲娇小性xxxx色| 亚洲国产日产无码精品| 亚洲精品美女在线观看播放| 7777久久亚洲中文字幕蜜桃| 久久精品国产亚洲77777| 伊人久久综在合线亚洲2019| 亚洲AV成人片色在线观看高潮 | 亚洲欧美第一成人网站7777| 亚洲人成电影网站色www| 亚洲av无码专区在线电影天堂 | 亚洲av成人一区二区三区| 亚洲三级在线视频| 亚洲一区精彩视频| 亚洲欧美日韩中文高清www777| 亚洲人xxx日本人18| 最新国产精品亚洲| 亚洲国产精品无码第一区二区三区| 亚洲精品无码你懂的| 久久精品国产亚洲av天美18| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲国产成人乱码精品女人久久久不卡 | 色天使亚洲综合一区二区| 国产亚洲蜜芽精品久久| 亚洲欧洲日产国码高潮αv| 亚洲精品亚洲人成人网| 亚洲嫩草影院久久精品| 亚洲成a人不卡在线观看| 亚洲国产精品综合久久20| 亚洲人成色在线观看| 国产成人亚洲综合a∨| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 亚洲男人的天堂在线va拉文| 亚洲人成在线播放网站| 久久噜噜噜久久亚洲va久| 亚洲福利秒拍一区二区| 亚洲中文字幕久久无码|