螞蟻二面,面試官問我零拷貝的實現原理,當場懵了…

Intellij IDEA 又過期了? 試試這個

"狼哥,面試又跪了,碰到了知識盲區"
"哪個?"
"一面還可以,二面面試官問我零拷貝的原理,懵逼了...這塊內容沒去研究過"
"哦,這個知識點,我之前應該有講過,你沒注意到?"
"這東西工作中用不到,可能被我忽略了"
"嘖嘖嘖..."
"哎,有空和我大概講講?"

"先從簡單開始,實現下這個場景:從一個文件中讀出數據并將數據傳到另一臺服務器上?"

"為啥寫這個?"

"你先寫"

"行..."

1分鐘后

"我寫了偽代碼"

File.read(file, buf, len);
Socket.send(socket, buf, len);

"這里涉及到了幾次數據拷貝?"

"2次?磁盤拷貝到內存,內存拷貝到Socket?"

"emmm,怪不得掛了,一點不冤。"

"這種方式一共涉及了4次數據拷貝,知道用戶態和內核態的區別嗎?"

"了解"

"行,文字有點干癟,你先看這個圖"

image.png

1、應用程序中調用read() 方法,這里會涉及到一次上下文切換(用戶態->內核態),底層采用DMA(direct memory access)讀取磁盤的文件,并把內容存儲到內核地址空間的讀取緩存區。

2、由于應用程序無法讀取內核地址空間的數據,如果應用程序要操作這些數據,必須把這些內容從讀取緩沖區拷貝到用戶緩沖區。這個時候,read() 調用返回,且引發一次上下文切換(內核態->用戶態),現在數據已經被拷貝到了用戶地址空間緩沖區,這時,如果有需要,應用程序可以操作修改這些內容。

3、我們最終目的是把這個文件內容通過Socket傳到另一個服務中,調用Socket的send()方法,這里又涉及到一次上下文切換(用戶態->內核態),同時,文件內容被進行第三次拷貝,被再次拷貝到內核地址空間緩沖區,但是這次的緩沖區與目標套接字相關聯,與讀取緩沖區沒有半點關系。

4、send()調用返回,引發第四次的上下文切換,同時進行第四次的數據拷貝,通過DMA把數據從目標套接字相關的緩存區傳到協議引擎進行發送。

"在整個過程中,過程1和4是由DMA負責,并不會消耗CPU,只有過程2和3的拷貝需要CPU參與,整明白了?"

"我消化一下..."

半小時后...

"狼哥,這個過程,感覺好幾次的數據拷貝都是多余的,很影響性能啊"

"對,所以才有了零拷貝技術"

"具體咋實現?"

"慢慢來,如果在應用程序中,不需要操作內容,過程2和3就是多余的,如果可以直接把內核態讀取緩存沖區數據直接拷貝到套接字相關的緩存區,是不是可以達到優化的目的?"

這種實現,可以有以下幾點改進:

  • 上下文切換的次數從四次減少到了兩次
  • 數據拷貝次數從四次減少到了三次(其中DMA copy 2次,CPU copy 1次)

"怎么實現?"

"在Java中,正好FileChannel的transferTo() 方法可以實現這個過程,該方法將數據從文件通道傳輸到給定的可寫字節通道, 上面的file.read()socket.send() 調用動作可以替換為 transferTo() 調用"

public void transferTo(long position, long count, WritableByteChannel target);

在 UNIX 和各種 Linux 系統中,此調用被傳遞到 sendfile() 系統調用中,最終實現將數據從一個文件描述符傳輸到了另一個文件描述符。

"確實改善了很多,但還沒達到零拷貝的要求,還有其它黑技術嗎?"

"對的,如果底層網絡接口卡支持收集操作的話,就可以進一步的優化。"

"怎么優化?"

在 Linux 內核 2.4 及后期版本中,針對套接字緩沖區描述符做了相應調整,DMA自帶了收集功能,對于用戶方面,用法還是一樣的,但是內部操作已經發生了改變:

  • 第一步,transferTo() 方法引發 DMA 將文件內容拷貝到內核讀取緩沖區。
  • 第二步,把包含數據位置和長度信息的描述符追加到套接字緩沖區,避免了內容整體的拷貝,DMA 引擎直接把數據從內核緩沖區傳到協議引擎,從而消除了最后一次 CPU參與的拷貝動作。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370