本文是對參考文章重要部分的摘錄,同時進行簡單地總結。linux
傳統的 Linux 操做系統的標準 I/O 接口是基於數據拷貝操做的,即 I/O 操做會致使數據在操做系統內核地址空間的緩衝區和應用程序地址空間定義的緩衝區之間進行傳輸,這樣作最大的好處是能夠減小實際的物理磁盤 I/O 操做。可是數據傳輸過程當中的數據拷貝操做卻致使了極大的 CPU 開銷,限制了操做系統有效進行數據傳輸操做的能力。編程
簡單一點來講,零拷貝就是一種避免 CPU 將數據從一塊存儲拷貝到另一塊存儲的技術。
零拷貝技術能夠減小數據拷貝和共享總線操做的次數,消除傳輸數據在存儲器之間沒必要要的中間拷貝次數,從而有效地提升數據傳輸效率。並且,零拷貝技術減小了用戶應用程序地址空間和操做系統內核地址空間之間由於上下文切換而帶來的開銷。
針對操做系統中的設備驅動程序、文件系統以及網絡協議堆棧而出現的各類零拷貝技術極大地提高了特定應用程序的性能,而且使得這些應用程序能夠更加有效地利用系統資源。
緩存
不少網絡服務器都是基於客戶端 - 服務器這一模型的。在這種模型中,客戶端向服務器端請求數據或者服務;服務器端則須要響應客戶端發出的請求,併爲客戶端提供它所須要的數據。隨着網絡服務的逐漸普及,video 這類應用程序發展迅速。當今的計算機系統已經具有足夠的能力去處理 video 這類應用程序對客戶端所形成的重負荷,可是對於服務器端來講,它應付由 video 這類應用程序引發的網絡通訊量就顯得捉襟見肘了。舉個例子來講,當數據「寫」操做或者數據「發送」操做的系統調用發出時,操做系統一般都會將數據從應用程序地址空間的緩衝區拷貝到操做系統內核的緩衝區中去。操做系統這樣作的好處是接口簡單,可是卻在很大程度上損失了系統性能,由於這種數據拷貝操做不單須要佔用 CPU 時間片,同時也須要佔用額外的內存帶寬。安全
通常來講,一個 CPU 時鐘週期能夠處理一位的數據。舉例來講,一個 1 GHz 的處理器能夠對 1Gbit/s 的網絡連接進行傳統的數據拷貝操做,可是若是是 10 Gbit/s 的網絡,那麼對於相同的處理器來講,零拷貝技術就變得很是重要了。服務器
Linux 中傳統服務器進行數據傳輸的流程以下。
當應用程序須要訪問某塊數據的時候,操做系統內核會先檢查這塊數據是否是由於前一次對相同文件的訪問而已經被存放在操做系統內核地址空間的緩衝區內,若是在內核緩衝區中找不到這塊數據,Linux 操做系統內核會先將這塊數據從磁盤讀出來放到操做系統內核的緩衝區裏去。若是這個數據讀取操做是由 DMA 完成的,那麼在 DMA 進行數據讀取的這一過程當中,CPU 只是須要進行緩衝區管理,以及建立和處理 DMA ,除此以外,CPU 不須要再作更多的事情,DMA 執行完數據讀取操做以後,會通知操做系統作進一步的處理。Linux 操做系統會根據 read() 系統調用指定的應用程序地址空間的地址,把這塊數據存放到請求這塊數據的應用程序的地址空間中去,在接下來的處理過程當中,操做系統須要將數據再一次從用戶應用程序地址空間的緩衝區拷貝到與網絡堆棧相關的內核緩衝區中去,這個過程也是須要佔用 CPU 的。數據拷貝操做結束之後,調用 write() 系統調用時,數據會被打包,而後發送到網絡接口卡上去,這個操做也能夠經過DMA完成。在數據傳輸的過程當中,應用程序能夠先返回進而執行其餘的操做。以後,在調用 write() 系統調用的時候,用戶應用程序緩衝區中的數據內容能夠被安全的丟棄或者更改,由於操做系統已經在內核緩衝區中保留了一份數據拷貝,當數據被成功傳送到硬件上以後,這份數據拷貝就能夠被丟棄。
物理磁盤 》 內核頁緩存 》 應用程序緩衝區 》 內核協議棧緩衝區 》 物理網卡緩衝區,去掉兩次 DMA 拷貝操做,CPU 還得參與兩次拷貝操做。網絡
直接 I/O 是相對於緩存 I/O 的。緩存 I/O 又被稱做標準 I/O,大多數文件系統的默認 I/O 操做都是緩存 I/O。在 Linux 的緩存 I/O 機制中,操做系統會將 I/O 的數據緩存在文件系統的頁緩存( page cache )中,也就是說,數據會先被拷貝到操做系統內核的緩衝區中,而後纔會從操做系統內核的緩衝區拷貝到應用程序的地址空間。在緩存 I/O 機制中,DMA 方式能夠將數據直接從磁盤讀到頁緩存中,或者將數據從頁緩存直接寫回到磁盤上,而不能直接在應用程序地址空間和磁盤之間進行數據傳輸,這樣的話,數據在傳輸過程當中須要在應用程序地址空間和頁緩存之間進行屢次數據拷貝操做,這些數據拷貝操做所帶來的 CPU 以及內存開銷是很是大的。
對於某些特殊的應用程序來講,避開操做系統內核緩衝區而直接在應用程序地址空間和磁盤之間傳輸數據會比使用操做系統內核緩衝區獲取更好的性能,這就是直接 I/O 要解決的問題。直接 I/O 徹底不須要 Linux 操做系統內核提供的頁緩存的支持。可是直接 I/O 有時候也會對性能產生負面影響,因此應用程序使用直接 I/O 進行數據傳輸的時候一般會和使用異步 I/O 結合使用。
物理磁盤 》 應用程序緩衝區 》 物理網卡緩衝區。app
有的時候,應用程序在數據進行傳輸的過程當中不須要對數據進行訪問,那麼,將數據從 Linux 的頁緩存拷貝到用戶進程的緩衝區中就能夠徹底避免,傳輸的數據在頁緩存中就能夠獲得處理。
在某些特殊的狀況下,這種零拷貝技術能夠得到較好的性能。Linux 中提供相似的系統調用主要有 mmap(),sendfile() 以及 splice()。
物理磁盤 》 內核頁緩存 》 內核協議棧緩衝區 》 物理網卡緩衝區。異步
該零拷貝技術側重於靈活地處理數據在用戶進程的緩衝區和操做系統的頁緩存之間的拷貝操做。這種方法延續了傳統的通訊方式,這算是對前兩種技術的一個折中,可是更加靈活。在 Linux 中,該方法主要利用了寫時複製技術。ide
寫時複製是計算機編程中的一種優化策略,它的基本思想是這樣的:若是有多個應用程序須要同時訪問同一塊數據,那麼能夠爲這些應用程序分配指向這塊數據的指針,在每個應用程序看來,它們都擁有這塊數據的一份數據拷貝,當其中一個應用程序須要對本身的這份數據拷貝進行修改的時候,就須要將數據真正地拷貝到該應用程序的地址空間中去,也就是說,該應用程序擁有了一份真正的私有數據拷貝,這樣作是爲了不該應用程序對這塊數據作的更改被其餘應用程序看到。這個過程對於應用程序來講是透明的,若是應用程序永遠不會對所訪問的這塊數據進行任何更改,那麼就永遠不須要將數據拷貝到應用程序本身的地址空間中去。
寫時複製的最大好處就是能夠節約內存。不過對於操做系統內核來講,寫時複製增長了其處理過程的複雜性。性能
Zero-copy versions of operating system elements, such as device drivers, file systems, and network protocol stacks, greatly increase the performance of certain application programs and more efficiently utilize system resources.
Techniques for creating zero-copy software include the use of DMA-based copying and memory-mapping through an MMU. These features require specific hardware support and usually involve particular memory alignment requirements.
避免數據拷貝
將多種操做結合在一塊兒
參考:Zero-copy、Linux 中的零拷貝技術,第 1 部分、Linux 中的零拷貝技術,第 2 部分、Linux 中直接 I/O 機制的介紹。