零拷貝、mmap、sendfile

目錄

    • 零拷貝
    • mmap
    • sendFile
    • 總結

零拷貝

要了解零拷貝,首先得先了解一下傳統 IO 的執行流程,這里舉個例子,通過傳統的 IO 進行網絡傳輸來傳輸一個文件。
在這里插入圖片描述
先上一張圖,這張圖就代表了傳統 IO 傳輸文件的流程。

讀取文件的時候,會從用戶態切換為內核態,同時基于 DMA 引擎將磁盤文件拷貝到內核緩沖區。

看到這里,可能你就已經懵逼了,什么是用戶態和內核態,什么是 DMA 拷貝,我用大白話解釋一下

首先用戶態其實就是 CPU 在執行你的代碼,而內核態呢,其實就是你沒有那個權限去操作硬件,所以只能交給系統去調用,這個時候就是內核態。舉個例子,你的女朋友需要你修個電腦(醒醒,但凡有一粒花生米也不至于喝成這樣),我換個說法,假如你同班的女同學想讓你修個電腦,但是宿管阿姨不肯放你進女生宿舍,這個時候你就是用戶態,你不能進女生宿舍,所以你只能讓宿管阿姨(內核態)來幫你把電腦取出來。

那什么是 DMA 拷貝呢,DMA(DirectMemoryAccess,直接內存存取)其實就是因為 CPU 老哥太累了,所以找了個小弟,就是 DMA 替他完成一部分的拷貝工作,這樣 CPU 就能去做其他事情了。

講完了內核態和用戶態還有 DMA 的大概意思,我們接著回到剛才的 IO 流程中,第一步我們將文件從磁盤文件讀到了用戶緩沖區,此時經歷了一次上下文切換和一次拷貝。

由內核態切換為用戶態,基于 CPU 把內核緩沖區的數據拷貝到用戶緩沖區。

調用 socket 的輸出流的 write 方法的話,此時會從用戶態切換到內核態,同時基于 CPU把用戶緩沖區里的數據拷貝到 Socket 緩沖區里去,接著會有一個異步化的過程,基于 DMA 引擎從 Socket 緩沖區里把數據拷貝到網絡協議引擎里發送出去。

當 IO 操作完成之后,又從內核態切換為用戶態。

通過上面的步驟可以發現傳統的 IO 操作執行,有 4 次上下文的切換和 4 次拷貝,是不是很繁瑣。

零拷貝的話,一般有 mmap 和 sendFile 兩種,一個一個來說。

mmap

mmap 是一種內存映射技術,mmap 相比于傳統的 IO 來說,其實就是少了 1 次 CPU 拷貝而已,上圖。
在這里插入圖片描述
傳統 IO 里面從內核緩沖區到用戶緩沖區有一次 CPU 拷貝,從用戶緩沖區到 Socket 緩沖區又有一次 CPU 拷貝。mmap 則一步到位,直接基于 CPU 將內核緩沖區的數據拷貝到了 Socket 緩沖區。

之所以能夠減少一次拷貝,就是因為 mmap 直接將磁盤文件數據映射到內核緩沖區,這個映射的過程是基于 DMA 拷貝的,同時用戶緩沖區是跟內核緩沖區共享一塊映射數據的,建立共享映射之后,就不需要從內核緩沖區拷貝到用戶緩沖區了。

雖然減少了一次拷貝,但是上下文切換的次數還是沒變。

RocketMQ 中就是使用的 mmap 來提升磁盤文件的讀寫性能。

sendFile

在 Linux 中,提供 sendFile 函數,實現了零拷貝,依舊是先上圖。
在這里插入圖片描述
可以看到在圖中,已經沒有了用戶緩沖區,因為用戶緩沖區是在用戶空間的,所以沒有了用戶緩沖區也就意味著不需要上下文切換了,就省略了這一步的從內核態切換為用戶態。

同時也不需要基于 CPU 將內核緩沖區的數據拷貝到 Socket 緩沖區了,只需要從內核緩沖區拷貝一些 offset 和 length 到 Socket 緩沖區。

接著從內核態切換到用戶態,從內核緩沖區直接把數據拷貝到網絡協議引擎里去;同時從 Socket 緩沖區里拷貝一些 offset 和 length 到網絡協議引擎里去,但是這個 offset 和 length 的量很少,幾乎可以忽略。

sendFile 整個過程只有兩次上下文切換和兩次 DMA 拷貝,很重要的一點是這里完全不需要 CPU 來進行拷貝了,所以才叫做零拷貝,這里的拷貝指的就是操作系統的層面。

那你肯定會問,那 mmap 里面有一次 CPU 拷貝為啥也算零拷貝,只能說那不算是嚴格意義上的零拷貝,但是他確實是優化了普通 IO 的執行流程,就像老婆餅里也沒有老婆嘛。

Kafka 和 Tomcat 內部使用就是 sendFile 這種零拷貝。

總結

傳統 IO 執行的話需要 4 次上下文切換(用戶態 -> 內核態 -> 用戶態 -> 內核態 -> 用戶態)和 4 次拷貝(磁盤文件 DMA 拷貝到內核緩沖區,內核緩沖區 CPU 拷貝到用戶緩沖區,用戶緩沖區 CPU 拷貝到 Socket 緩沖區,Socket 緩沖區 DMA 拷貝到協議引擎)。

mmap 將磁盤文件映射到內存,支持讀和寫,對內存的操作會反映在磁盤文件上,適合小數據量讀寫,需要 4 次上下文切換(用戶態 -> 內核態 -> 用戶態 -> 內核態 -> 用戶態)和3 次拷貝(磁盤文件DMA拷貝到內核緩沖區,內核緩沖區 CPU 拷貝到 Socket 緩沖區,Socket 緩沖區 DMA 拷貝到協議引擎)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378933.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378933.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378933.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網頁服務器和mysql服務器_實現Web服務器之間使用同一個MYSQL和相同的網頁配置文件的方法...

實現Web服務器之間使用同一個MYSQL和相同的網頁配置文件的方法發布時間:2020-04-15 16:42:41來源:億速云閱讀:133作者:三月欄目:數據庫億速云負載均衡(Cloud Load Balancer)是對多臺云服務器進行流量分發的服務。億速云…

傳128GB版iPad4售價為799/929美元

外媒9to5mac報道,蘋果將推出一款升級版iPad4,外觀和iPad 4相同,還是黑白兩色的,只加入了新的SKU。 據報道,這款升級版iPad4還有128GB版,隨著這條消息傳出,不久關于128GB版iPad4的售價信息也傳出…

(西工程-金花)小米路由器連接哆點設置WiFi保姆式教程

小米路由器連接電源,用根網線一端插入寢室的網口處,另一端插入小米路由器的WAN口手機或者電腦連接WiFi,我這里是通過手機瀏覽器打開192.168.31.1進入無線路由器管理頁面進行配置小米路由器,配置WiFi的一些基本參數,例如:WiFi名稱,密碼之類的信息 進入無線路由器管理…

基于MINA框架快速開發網絡應用程序

1.MINA框架簡介 Netty、Mina、Cindy都是不錯的NIO開源框架,后兩者都是在Netty的基礎上演化出來的。MINA(Multipurpose Infrastructure for Network Applications)是用于開發高性能和高可用性的網絡應用程序的基礎框架。通過使用MINA框架可以可以省下處理…

Python中@staticmethod和@classmethod之間的區別

classmethod裝飾器 (The classmethod Decorator) The classmethod decorator is an inbuilt function decorator that gets evaluated after the function is defined. The result of the evaluation shadows the function definition. The classmethods first argument is alw…

go 聲明二維數組_一篇文章了解Go語言中數組Arrays的使用內幕

概述與其他編程語言類似,Go語言也有數組array。Go語言中,數組的行為和其他語言沒有什么不同.Go語言中還有一個叫做切片slice的東西,它就像是對數組的引用。在本文中,我們將只研究數組。定義數組是同一類型元素的連續集合&#xff…

ffmpeg 使用ffplay 進行 hls 拉流 分析 1

ffmpeg 使用 ffplay 進行 hls 拉流 分析 1 從使用ffplay 調用 http://192.168.1.100:8080/live/livestream.m3u8 開始,進入到ffmpeg 的分析使用的協議選擇相應的解復用器的步驟。 其他協議或者文件方式的使用ffplay也是這個步驟流程的。 目錄:一、流程圖…

搜狗輸入法輸出特殊符號快捷鍵

https://www.petefreitag.com/cheatsheets/ascii-codes/ 參考上個編碼網站大全 詳細步驟為:alt長按 + 編碼數字 例如:平方的編碼為178-----長按alt178 即可,178是數字一個一個挨個按即可 常用的特殊符號如下: 平方&…

echo 12345678 | base64 產生的結果跟12345678真正的base64編碼不對

echo "12345678" | base64 產生的結果跟"12345678"真正的base64編碼不對 弄了好久才搞清楚,echo 命令是帶換行符的,改成echo -n "12345678" | base64就沒問題了轉載于:https://www.cnblogs.com/senix/archive/2013/01/30/…

[BuildRelease Management]CC.NET架構

一 CC.NET的操作流程 1) 等待Trigger的喚醒; 2)從Source Control System查詢上次build以后的修改列表; 3)如果任何修改被發現或是Trigger觸發類型為 force the build : 3.1)為build產生一個label number&a…

python 入門到實踐期末考試常出現的考試內容_Python編程入門到實踐—列表篇(一)...

一、列表是什么?列表由一系列按特定順序排列的元素組成。可以創建包含字母表中所有字母、數字0-9或所有家庭成員姓名的列表;也可以將任何東西加入列表中,其中的元素之間可以沒有任何關系。列表通常包含多個元素,給列表指定一個表示…

c#中將集合寫入文本_在C#中將記錄插入MySQL數據庫

c#中將集合寫入文本In the last tutorial (how to connect with MySQL database in C#?), we learned about making the connection with MySQL database in C#. Here, in this tutorial, we will learn how to insert the records in MySQL database in C#? 在上一教程( 如何…

read/fread write/fwrite 的區別

fread就是通過read來實現的,fread是C語言的庫,而read是系統調用。 差別在read每次讀的數據是調用者要求的大小,比如調用者要求讀取10個字節數據,read就會從內核緩沖區(操作系統開辟的一段空間用來存儲磁盤上的數據&am…

如何在子網中訪問上層網絡的計算機文件夾

場景 公司路由器A,直接接外部網線,內部ip192.168.11.1,lan口又接了路由器A1,IP為192.168.11.2,A1的lan端口接了一臺電腦A,Ip為192.168.0.2,接了另外一個路由A2,Ip為192.168.11.3&…

基于Web的套打方案分析

應用web化,不論對開發商,還是對用戶來說,實在是一種很經濟的選擇,因為基于web的應用,客戶端的規則很簡單,容易學習,容易維護,容易發布。但對程序員來說,因為瀏覽器的局限…

day1-Linux操作系統基礎

該專欄所有內容筆記均來自傳智播客培訓班 1.什么是操作系統(operate system OS) 小議:承上啟下作用,向下可以控制硬件,向上能夠支持軟件的運行。一個可以控制硬件的軟件。 小明找小紅聊天,小明打開QQ&…

關閉瀏覽器 清空session_跨境網絡小知識之Session

跨境小伙伴們大家好,上一篇為大家介紹了Cookie,今天就為大家介紹下連接cookie的另一端Session,交互過程中,二者缺一不可。與Cookie相對,Session是存儲在服務端的,他們之間是通過一個叫做sessionID的東東建立…

我和乘子交替方向法admm_找到最大和交替子序列

我和乘子交替方向法admmProblem statement: 問題陳述: Given a sequence of numbers, you have to find the maximum sum alternating subsequence and print the value. A sequence is an alternating sequence when it will be maintain like (increasing) ->…

Dojo學習筆記(一):Hello Dojo!

歡迎來到Dojo世界!在這篇文章中你將會學習到如何加載Dojo以及探索Dojo的一些核心功能。你還會了解Dojo的基于AMD的模塊架構,探索如何加載額外的模塊來增加功能到您的Web站點或應用程序,并找出在出錯的時如何得到幫助。讓我們開始吧 開始學習D…

轉:我眼中的Visual Studio 2010架構工具

來自:http://www.cnblogs.com/wayfarer/archive/2010/07/30/1788398.html我眼中的Visual Studio 2010架構工具影響架構質量的是構建體系架構的思想、原則、實踐與架構師的經驗,絕不是工具。即使是最優秀的架構工具,也不可能像倚天寶劍一般——…