【Linux編程】大冒險(xiǎn)之零拷貝技術(shù)探究

原文: https://blog.csdn.net/lk_wkqd/article/details/50242523

對于網(wǎng)絡(luò)數(shù)據(jù)傳輸或I/O數(shù)據(jù)拷貝而言,零拷貝技術(shù)主要指的是避免內(nèi)核緩沖區(qū)和用戶緩沖區(qū)中的不必要的數(shù)據(jù)拷貝操作。

Linux傳統(tǒng)I/O

Linux傳統(tǒng)I/O操作是一種緩沖I/O,在數(shù)據(jù)傳輸中,操作系統(tǒng)會(huì)將 I/O 的數(shù)據(jù)緩存在文件系統(tǒng)的頁緩存中,即操作系統(tǒng)內(nèi)核緩沖區(qū)中。
比如:在網(wǎng)絡(luò)中傳輸一個(gè)文件時(shí),發(fā)送端應(yīng)用程序會(huì)先檢查內(nèi)核緩沖區(qū)中有沒有需要發(fā)送的這個(gè)文件的數(shù)據(jù),如果沒有,則會(huì)將這個(gè)文件從磁盤拷貝到內(nèi)核緩沖區(qū)中,然后再從內(nèi)核緩沖區(qū)拷貝到應(yīng)用程序的用戶緩沖區(qū),如果應(yīng)用程序不對數(shù)據(jù)進(jìn)行處理或處理完畢之后,再將文件拷貝到內(nèi)核中的socket發(fā)送緩沖區(qū)(比如TCP發(fā)送緩沖區(qū)),待內(nèi)核socket緩沖區(qū)中有足夠的數(shù)據(jù)時(shí),就會(huì)把數(shù)據(jù)發(fā)送到網(wǎng)卡上,然后在網(wǎng)絡(luò)上進(jìn)行傳輸。其數(shù)據(jù)傳輸過程如下圖所示:

這里寫圖片描述

其過程至少發(fā)生了四次數(shù)據(jù)的拷貝,其頻繁的讀寫對CPU的使用和內(nèi)存的帶寬開銷是非常大的。

零拷貝技術(shù)

零拷貝技術(shù)相對傳統(tǒng)I/O技術(shù)來說,主要是避免數(shù)據(jù)傳輸過程中頻繁的數(shù)據(jù)拷貝操作,提高傳輸效率,并且使CPU有更多時(shí)間執(zhí)行其它任務(wù)。

零拷貝技術(shù)分類

  • 直接I/O機(jī)制:

通過上面的介紹,普通I/O(即緩沖I/O)會(huì)被內(nèi)核緩存。相對于普通I/O機(jī)制,直接I/O機(jī)制對文件的訪問不經(jīng)過內(nèi)核的緩存,數(shù)據(jù)直接在磁盤和應(yīng)用程序地址空間進(jìn)行傳輸。這就避免了內(nèi)核緩沖區(qū)和用戶緩沖區(qū)的數(shù)據(jù)拷貝,降低了讀寫操作對CPU的使用以及對內(nèi)存帶寬的占用。
但是直接 I/O 不能提供緩存 I/O 的優(yōu)勢。緩存 I/O 的讀操作可以從高速緩沖存儲(chǔ)器中快速獲取數(shù)據(jù),而直接 I/O 的讀數(shù)據(jù)操作會(huì)造成磁盤的同步讀,導(dǎo)致進(jìn)程需要較長的時(shí)間才能執(zhí)行完。

  • 不經(jīng)過用戶緩沖區(qū)

主要是指不需要將數(shù)據(jù)拷貝或者映射到應(yīng)用程序地址空間中,直接在內(nèi)核中傳輸。
比如sendfile( )系統(tǒng)調(diào)用:sendfile( ) 系統(tǒng)調(diào)用利用 DMA 將文件中的數(shù)據(jù)拷貝到操作系統(tǒng)內(nèi)核緩沖區(qū)中,然后數(shù)據(jù)被拷貝到與 socket 相關(guān)的內(nèi)核緩沖區(qū)中。接下來,DMA 將數(shù)據(jù)從內(nèi)核 socket 緩沖區(qū)中拷貝到網(wǎng)卡中去。如果在用戶調(diào)用 sendfile ( ) 系統(tǒng)調(diào)用進(jìn)行數(shù)據(jù)傳輸?shù)倪^程中有其他進(jìn)程截?cái)嗔嗽撐募?,那?sendfile ( ) 系統(tǒng)調(diào)用會(huì)簡單地返回給用戶應(yīng)用程序中斷前所傳輸?shù)淖止?jié)數(shù),errno 會(huì)被設(shè)置為 success。
其傳輸過程如下:

這里寫圖片描述

由于sendfile( )函數(shù)只能往socket上寫數(shù)據(jù),因此它幾乎是專門為了在網(wǎng)絡(luò)上傳輸文件而設(shè)計(jì)的。

DMA簡介:Direct Memory Access(存儲(chǔ)器直接訪問)。這是指一種高速的數(shù)據(jù)傳輸操作,允許在外部設(shè)備和存儲(chǔ)器之間直接讀寫數(shù)據(jù),既不通過CPU,也不需要CPU干預(yù)。整個(gè)數(shù)據(jù)傳輸操作在一個(gè)稱為”DMA控制器”的控制下進(jìn)行的。CPU除了在數(shù)據(jù)傳輸開始和結(jié)束時(shí)做一點(diǎn)處理外,在傳輸過程中CPU可以進(jìn)行其他的工作。這樣,在大部分時(shí)間里,CPU和輸入輸出都處于并行操作。因此,使整個(gè)計(jì)算機(jī)系統(tǒng)的效率大大提高。

  • 優(yōu)化數(shù)據(jù)在內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的傳輸

保留了傳統(tǒng)的在用戶應(yīng)用程序地址空間和操作系統(tǒng)內(nèi)核地址空間之間傳遞數(shù)據(jù)的技術(shù),但卻在傳輸上進(jìn)行優(yōu)化。
比如寫時(shí)復(fù)制技術(shù):如果多個(gè)應(yīng)用程序同時(shí)訪問同一塊數(shù)據(jù),但這塊數(shù)據(jù)只有一份,那么可以為這些應(yīng)用程序分配指向這塊數(shù)據(jù)的指針,在每一個(gè)應(yīng)用程序看來,它們都擁有這塊數(shù)據(jù)的一份數(shù)據(jù)拷貝。若一個(gè)應(yīng)用程序需要訪問但不修改該數(shù)據(jù)時(shí),直接讀這個(gè)數(shù)據(jù)而不復(fù)制,但當(dāng)應(yīng)用程序需要對這塊數(shù)據(jù)進(jìn)行修改的時(shí)候,就需要將數(shù)據(jù)真正地拷貝到該應(yīng)用程序的地址空間中去,也就是說,該應(yīng)用程序擁有了一份真正的私有數(shù)據(jù)拷貝,對這份私有數(shù)據(jù)進(jìn)行修改。這樣做是為了避免該應(yīng)用程序?qū)@塊數(shù)據(jù)做的更改被其他應(yīng)用程序看到。這個(gè)過程對于應(yīng)用程序來說是透明的,如果應(yīng)用程序永遠(yuǎn)不會(huì)對所訪問的這塊數(shù)據(jù)進(jìn)行任何更改,那么就永遠(yuǎn)不需要將數(shù)據(jù)拷貝到應(yīng)用程序自己的地址空間中去。

以上只進(jìn)行了比較淺的分析,知識(shí)有限,找了一些深入的資料沒有看懂,比如其實(shí)現(xiàn)機(jī)理,等需要對Linux內(nèi)核深入學(xué)習(xí)的時(shí)候在回頭看,不過暫時(shí)理解這些對于網(wǎng)絡(luò)編程已經(jīng)有很大的幫助了。

相關(guān)資料
Linux 中的零拷貝技術(shù)第 1 部分
Linux 中的零拷貝技術(shù)第 2 部分

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是零拷貝 維基上是這么描述零拷貝的:零拷貝描述的是CPU不執(zhí)行拷貝數(shù)據(jù)從一個(gè)存儲(chǔ)區(qū)域到另一個(gè)存儲(chǔ)區(qū)域的任務(wù),這...
    tomas家的小撥浪鼓閱讀 28,381評論 11 62
  • 本文探討Linux中主要的幾種零拷貝技術(shù)以及零拷貝技術(shù)適用的場景。為了迅速建立起零拷貝的概念,我們拿一個(gè)常用的場景...
    卡巴拉的樹閱讀 66,541評論 13 112
  • 十七歲那年,我戀愛了。這是因?yàn)橐恢庇∠蟛诲e(cuò)的男生成了我的同桌。 一開始只是聊的來,漸漸的成了好哥們兒,現(xiàn)在想來,我...
    貝莉爾de璞玉為石閱讀 167評論 0 0
  • Rx,不管你是JS,Java,Python還是Swift,玩的就是操作符。每個(gè)操作符怎么用,官方文檔寫得不能再清楚...
    du1dume閱讀 14,585評論 1 15
  • 人常言“讀萬卷書不如行萬里路,行萬里路不如高人指路”,雖然這句話幾乎所有人都耳熟能詳,包括我自己,可是我卻并沒有意...
    今天安好閱讀 629評論 0 0

友情鏈接更多精彩內(nèi)容