Zero Copy 學習總結

xz43發表於2020-01-02

定義

零複製(英語:Zero-copy;也譯零拷貝)技術是指計算機執行操作時,CPU不需要先將資料從某處記憶體複製到另一個特定區域。這種技術通常用於通過網路傳輸檔案時節省CPU週期和記憶體頻寬。

傳統IO讀寫方式

在讀取檔案資料,然後傳送到網路的這個場景中,傳統IO讀寫方式的過程如下。

Zero Copy 學習總結

由圖可知,整個過程總共發生了 4 次拷貝和 4 次使用者態和核心態的切換。其中

  1. 把磁碟中檔案拷貝到kernel buf

  2. 把kernel buf拷貝到user buf

  3. 把user buf拷貝到socket 中的kernel buf

  4. 把socket buffer 拷貝到網路卡裝置的buffer

所以說,一共拷貝4次,而且kernel mod和user mod的切換也是4次。使用者態和核心態的切換如下。借個網上的圖。


Zero Copy 學習總結

zero copy技術

Linux 2.1 核心開始引入了sendfile函式。省去了將作業系統的 read buffer 拷貝到程式的buffer,以及從程式buffer拷貝到socket buffer的步驟,而是直接將kernel buf 拷貝 到 socket buf。 實際上就是把上面的第2,3兩個步驟整合了。
Zero Copy 學習總結

減少不必要的核心緩衝區跟使用者緩衝區間的拷貝,從而減少CPU的開銷和核心態切換開銷,達到效能的提升。

Zero Copy 學習總結

transferTo()方法使得磁碟檔案的資料,首先被直接拷貝到一個read buffer(kernel buffer)中,然後 kernel buffer 的資料拷貝到 socket buffer 中,最後將 socket buffer 中的資料拷貝到網路卡裝置(protocol engine)中進行傳輸。

zero copy下,同樣的讀取檔案然後通過網路傳送出去,只需要拷貝 3 次,核心態和使用者態的切換從原來的4次減少為2次。


Linux2.4 核心對sendfile做了改進,如圖:

Zero Copy 學習總結

改進後,執行步驟如下:

  1. 將檔案拷貝到kernel buffer中;
  2. 向socket buf中寫入當前要拷貝資料在 kernel buffer 中的位置和偏移量;
  3. 根據socket buffer中的位置和偏移量,直接將kernel buffer的資料拷貝到網路卡protocol buffer中。

經過上述過程,資料只經過了2次copy就從磁碟傳送出去了。這才是真正的Zero-Copy( 這裡的零拷貝是針對kernel來講的,資料在kernel模式下是Zero-Copy
正是因為 Linux2.4 的核心做了改進,Java中的TransferTo()才實現了真正的 Zero-Copy,如下圖:

Zero Copy 學習總結

Zero-Copy技術的使用場景有很多,比如Kafka, 又或者是Netty等,可以大大提升程式的效能。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9399028/viewspace-2671693/,如需轉載,請註明出處,否則將追究法律責任。