零拷貝初探

2021-10-24 23:38:51 字數 2473 閱讀 2223

什麼是零拷貝?

零拷貝技術,就是避免將資料從一塊儲存拷貝到另外一塊儲存的技術,從而節省拷貝帶來的cpu開銷,零拷貝並不是將拷貝操作完全消除掉。

傳統拷貝

傳統的linux系統中,標準的i/o介面(例如read,write)都是基於資料拷貝操作的,即是i/o操作會導致資料在核心位址空間的緩衝區和使用者位址空間的緩衝區之間進行拷貝,所以標準i/o也被稱作快取i/o。這樣做的好處是,如果所請求的資料已經存放在核心的高速緩衝儲存器中,那麼就可以減少實際的i/o操作,但壞處就是資料拷貝的過程,會導致cpu開銷。

dma(direct memory access):直接儲存器訪問。dma是一種無需cpu的參與,讓外設和系統記憶體之間進行雙向資料傳輸的硬體機制。當dma完成資料的傳送之後,使用系統中斷提醒cpu,然後cpu就可以高效的處理資料。使用dma可以使系統cpu從實際的i/o資料傳輸過程中擺脫出來,從而大大提高系統的吞吐率。

我們可以看到需要經歷四個階段,2次dma,2次cpu中斷,總共四次拷貝,有四次上下文切換,並且會占用兩次cpu。

cpu發指令給i/o裝置的dma,由dma將我們磁碟中的資料傳輸到核心空間的核心buffer。

第二階段觸發我們的cpu中斷,cpu開始將將資料從kernel buffer拷貝至我們的應用快取

cpu將資料從應用快取拷貝到核心中的socket buffer.

dma將資料從socket buffer中的資料拷貝到網絡卡快取。

優點:開發成本低,適合一些對效能要求不高的,比如一些什麼管理系統這種我覺得就應該夠了

缺點:多次上下文切換,占用多次cpu,效能比較低。

mmap方式的拷貝

我們提到使用者態的程序是不能隨意操作核心位址空間的,而且mmap也沒有提供使用者程序直接操作核心位址空間的能力,而是通過記憶體對映的機制,把核心中的部分記憶體空間對映到使用者空間的記憶體,使用者空間和核心空間共享一塊相同的物理記憶體,從而提供使用者程序對記憶體直接訪問的能力。

有了mmap的支援,資料從檔案中讀取到核心空間之後,就不會再拷貝到使用者空間,當呼叫socket的write時,資料會直接從核心快取中直接拷貝到socket的緩衝區中,避免了在使用者空間中多中轉一次。

我們可以看到,mmp與傳統的拷貝方式相比,mmp減少了資料在使用者空間進行一次拷貝mmap雖然能減少一次資料拷貝,但是還是需要4次上下文切換,拷貝的話需要執行三次,即兩次dma拷貝,一次cpu的拷貝:

sendfile方式的拷貝

sendfile核心呼叫是在linux 2.1版本開始引入的,主要功能是在核心態中,在兩個檔案描述符之間傳遞資料,避免了使用者空間和核心空間之間的資料拷貝操作。

使用sendfile時,資料中轉與mmap類似,不經過使用者空間,但是由於sendfile全程在核心態執行,因此只需要2次上下文切換:

在linux 2.4版本中,對sendfile進一步做了優化,之前從「檔案資料快取」到「socket快取」時候,也需要一次拷貝,優化之後,「socket快取」中只儲存要傳送的資料在「檔案資料快取」中的位置和偏移量,在實際傳送時,根據位置和偏移量直接將「檔案資料快取」中的資料拷貝到網絡卡裝置中,又省掉了一次拷貝操作。

基於 sendfile和dma系統呼叫的零拷貝方式,整個拷貝過程會發生2 次上下文切換、0 次 cpu 拷貝以及 2 次 dma 拷貝使用者程式讀寫資料的流程如下:

使用者程序通過 sendfile() 函式向核心(kernel)發起系統呼叫,上下文從使用者態(user space)切換為核心態(kernel space)。

cpu 利用 dma 控制器將資料從主存或硬碟拷貝到核心空間(kernel space)的讀緩衝區(read buffer)。

cpu 把讀緩衝區(read buffer)的檔案描述符(file descriptor)和資料長度拷貝到網路緩衝區(socket buffer)。

基於已拷貝的檔案描述符(file descriptor)和資料長度,cpu 利用 dma 控制器的 gather/scatter 操作直接批量地將資料從核心的讀緩衝區(read buffer)拷貝到網絡卡進行資料傳輸。

上下文從核心態(kernel space)切換回使用者態(user space),sendfile 系統呼叫執行返回。

但是使用這種方式也是有缺點的,就是我們再拷貝的過程中不能對資料進行任何的修改,如果我們對資料進行修改後再進行拷貝的話這種方式就行不通了。如果我們要對檔案進行修改的話就必須使用傳統的拷貝方式了。

因為基於sendfile的這種特性,零拷貝技術被用在nginx等軟體上,提公升了很大的效率,比如我們使用nginx的時候對靜態資源的讀寫就會用到零拷貝,大大增加了我們伺服器的效能。

零拷貝問題

零拷貝 定義 避免cpu將資料從一塊儲存空間拷貝到另乙個儲存空間的技術。通常用於網路檔案傳輸 以減少cpu消耗和記憶體頻寬的占用 減少使用者空間 使用者可操作的記憶體快取區域 和cpu核心空間 cpu核心可操作的記憶體快取和暫存器快取 的拷貝過程,減少使用者上下文和cpu核心上下文的切換,讓cpu解...

零拷貝技術

一 應用場景 核心優化 快速拷貝檔案 filechannel至filechannel 二 產生原因 拷貝檔案 傳統傳輸檔案時,資料需要經過4次資料拷貝,分別為磁碟到核心快取 核心到使用者快取 使用者到核心快取 核心到磁碟,頻繁切換使用者態和核心態 三 解決方案 四 引數 引數作用和優點 缺點inpu...

NTZC零拷貝技術

network traffic zero copy 用於捕獲報文的零拷貝計數在網路上有很多的討論,但是目前看來還沒有乙個可用的 開源的實現。最接近的兩個實現 1 pf ring 仍然存在一次的拷貝 2 nta 由於年代較為久遠問題多多。ntzc基本的實現原理如下 1 專用核心模組zc將連續的若干記憶...