當前位置:首頁 > 公眾號精選 > CPP開發(fā)者
[導讀]↓推薦關注↓傳統(tǒng)的SystemCallI/O在Linux系統(tǒng)中,傳統(tǒng)的訪問方式是通過write()和read()兩個系統(tǒng)調用實現(xiàn)的,通過read()函數(shù)讀取文件到到緩存區(qū)中,然后通過write()方法把緩存中的數(shù)據(jù)輸出到網(wǎng)絡端口。read(file_fd,?tmp_buf,?le...

傳統(tǒng)的 System Call I/O

在 Linux 系統(tǒng)中,傳統(tǒng)的訪問方式是通過 write() 和 read() 兩個系統(tǒng)調用實現(xiàn)的,通過 read() 函數(shù)讀取文件到到緩存區(qū)中,然后通過 write() 方法把緩存中的數(shù)據(jù)輸出到網(wǎng)絡端口。


read(file_fd, tmp_buf, len);
write(socket_fd, tmp_buf, len); 下圖分別對應傳統(tǒng) I/O 操作的數(shù)據(jù)讀寫流程,整個過程涉及 2 次 CPU 拷貝、2 次 DMA 拷貝,總共 4 次拷貝,以及 4 次上下文切換。


  • CPU 拷貝:


    由 CPU 直接處理數(shù)據(jù)的傳送,數(shù)據(jù)拷貝時會一直占用 CPU 的資源。


  • DMA 拷貝:


    由 CPU 向DMA磁盤控制器下達指令,讓 DMA 控制器來處理數(shù)據(jù)的傳送,數(shù)據(jù)傳送完畢再把信息反饋給 CPU,從而減輕了 CPU 資源的占有率。


  • 上下文切換:


    當用戶程序向內核發(fā)起系統(tǒng)調用時,CPU 將用戶進程從用戶態(tài)切換到內核態(tài);


    當系統(tǒng)調用返回時,CPU 將用戶進程從內核態(tài)切換回用戶態(tài)。


讀操作

當應用程序執(zhí)行 read 系統(tǒng)調用讀取一塊數(shù)據(jù)的時候,如果這塊數(shù)據(jù)已經(jīng)存在于用戶進程的頁內存中,就直接從內存中讀取數(shù)據(jù)。


如果數(shù)據(jù)不存在,則先將數(shù)據(jù)從磁盤加載數(shù)據(jù)到內核空間的讀緩存(Read Buffer)中,再從讀緩存拷貝到用戶進程的頁內存中。


read(file_fd, tmp_buf, len);
基于傳統(tǒng)的 I/O 讀取方式,read 系統(tǒng)調用會觸發(fā) 2 次上下文切換,1 次 DMA 拷貝和 1 次 CPU 拷貝。


發(fā)起數(shù)據(jù)讀取的流程如下:


  1. 用戶進程通過 read() 函數(shù)向 Kernel 發(fā)起 System Call,上下文從 user space 切換為 kernel space。
  2. CPU 利用 DMA 控制器將數(shù)據(jù)從主存或硬盤拷貝到 kernel space 的讀緩沖區(qū)(Read Buffer)。
  3. CPU 將讀緩沖區(qū)(Read Buffer)中的數(shù)據(jù)拷貝到 user space 的用戶緩沖區(qū)(User Buffer)。
  4. 上下文從 kernel space 切換回用戶態(tài)(User Space),read 調用執(zhí)行返回。

寫操作

當應用程序準備好數(shù)據(jù),執(zhí)行 write 系統(tǒng)調用發(fā)送網(wǎng)絡數(shù)據(jù)時,先將數(shù)據(jù)從用戶空間的頁緩存拷貝到內核空間的網(wǎng)絡緩沖區(qū)(Socket Buffer)中,然后再將寫緩存中的數(shù)據(jù)拷貝到網(wǎng)卡設備完成數(shù)據(jù)發(fā)送。


write(socket_fd, tmp_buf, len);
基于傳統(tǒng)的 I/O 寫入方式,write() 系統(tǒng)調用會觸發(fā) 2 次上下文切換,1 次 CPU 拷貝和 1 次 DMA 拷貝。


用戶程序發(fā)送網(wǎng)絡數(shù)據(jù)的流程如下:


  1. 用戶進程通過 write() 函數(shù)向 kernel 發(fā)起 System Call,上下文從 user space 切換為 kernel space。
  2. CPU 將用戶緩沖區(qū)(User Buffer)中的數(shù)據(jù)拷貝到 kernel space 的網(wǎng)絡緩沖區(qū)(Socket Buffer)。
  3. CPU 利用 DMA 控制器將數(shù)據(jù)從網(wǎng)絡緩沖區(qū)(Socket Buffer)拷貝到 NIC 進行數(shù)據(jù)傳輸。
  4. 上下文從 kernel space 切換回 user space,write 系統(tǒng)調用執(zhí)行返回。

網(wǎng)絡 I/O

磁盤 I/O

高性能優(yōu)化的 I/O

  1. 零拷貝技術。
  2. 多路復用技術。
  3. 頁緩存(PageCache)技術。
其中,頁緩存(PageCache) 是操作系統(tǒng)對文件的緩存,用來減少對磁盤的 I/O 操作,以頁為單位的,內容就是磁盤上的物理塊,頁緩存能幫助程序對文件進行順序讀寫的速度幾乎接近于內存的讀寫速度,主要原因就是由于 OS 使用 PageCache 機制對讀寫訪問操作進行了性能優(yōu)化。


頁緩存讀取策略:當進程發(fā)起一個讀操作 (比如,進程發(fā)起一個 read() 系統(tǒng)調用),它首先會檢查需要的數(shù)據(jù)是否在頁緩存中:


  • 如果在,則放棄訪問磁盤,而直接從頁緩存中讀取。
  • 如果不在,則內核調度塊 I/O 操作從磁盤去讀取數(shù)據(jù),并讀入緊隨其后的少數(shù)幾個頁面(不少于一個頁面,通常是三個頁面),然后將數(shù)據(jù)放入頁緩存中。
頁緩存寫策略:當進程發(fā)起 write 系統(tǒng)調用寫數(shù)據(jù)到文件中,先寫到頁緩存,然后方法返回。此時數(shù)據(jù)還沒有真正的保存到文件中去,Linux 僅僅將頁緩存中的這一頁數(shù)據(jù)標記為 “臟”,并且被加入到臟頁鏈表中。


然后,由 flusher 回寫線程周期性將臟頁鏈表中的頁寫到磁盤,讓磁盤中的數(shù)據(jù)和內存中保持一致,最后清理“臟”標識。在以下三種情況下,臟頁會被寫回磁盤:


  1. 空閑內存低于一個特定閾值。


  2. 臟頁在內存中駐留超過一個特定的閾值時。


  3. 當用戶進程調用 sync() 和 fsync() 系統(tǒng)調用時。


存儲設備的 I/O 棧

由圖可見,從系統(tǒng)調用的接口再往下,Linux 下的 IO 棧致大致有三個層次:


  1. 文件系統(tǒng)層,以 write 為例,內核拷貝了 write 參數(shù)指定的用戶態(tài)數(shù)據(jù)到文件系統(tǒng) Cache 中,并適時向下層同步。


  2. 塊層,管理塊設備的 IO 隊列,對 IO 請求進行合并、排序(還記得操作系統(tǒng)課程學習過的 IO 調度算法嗎?)。


  3. 設備層,通過 DMA 與內存直接交互,完成數(shù)據(jù)和具體設備之間的交互。


結合這個圖,想想 Linux 系統(tǒng)編程里用到的 Buffered IO、mmap、Direct IO,這些機制怎么和 Linux I/O 棧聯(lián)系起來呢?上面的圖有點復雜,我畫一幅簡圖,把這些機制所在的位置添加進去:


Linux IO系統(tǒng)


這下一目了然了吧?傳統(tǒng)的 Buffered IO 使用 read 讀取文件的過程什么樣的?假設要去讀一個冷文件(Cache 中不存在),open 打開文件內核后建立了一系列的數(shù)據(jù)結構,接下來調用 read,到達文件系統(tǒng)這一層,發(fā)現(xiàn) Page Cache 中不存在該位置的磁盤映射,然后創(chuàng)建相應的 Page Cache 并和相關的扇區(qū)關聯(lián)。


然后請求繼續(xù)到達塊設備層,在 IO 隊列里排隊,接受一系列的調度后到達設備驅動層,此時一般使用 DMA 方式讀取相應的磁盤扇區(qū)到 Cache 中,然后 read 拷貝數(shù)據(jù)到用戶提供的用戶態(tài) buffer 中去(read 的參數(shù)指出的)。


整個過程有幾次拷貝? 從磁盤到 Page Cache 算第一次的話,從 Page Cache 到用戶態(tài) buffer 就是第二次了。而 mmap 做了什么?mmap 直接把 Page Cache 映射到了用戶態(tài)的地址空間里了,所以 mmap 的方式讀文件是沒有第二次拷貝過程的。


那 Direct IO 做了什么? 這個機制更狠,直接讓用戶態(tài)和塊 IO 層對接,直接放棄 Page Cache,從磁盤直接和用戶態(tài)拷貝數(shù)據(jù)。好處是什么?寫操作直接映射進程的buffer到磁盤扇區(qū),以 DMA 的方式傳輸數(shù)據(jù),減少了原本需要到 Page Cache 層的一次拷貝,提升了寫的效率。


對于讀而言,第一次肯定也是快于傳統(tǒng)的方式的,但是之后的讀就不如傳統(tǒng)方式了(當然也可以在用戶態(tài)自己做 Cache,有些商用數(shù)據(jù)庫就是這么做的)。


除了傳統(tǒng)的 Buffered IO 可以比較自由的用偏移 長度的方式讀寫文件之外,mmap 和 Direct IO 均有數(shù)據(jù)按頁對齊的要求,Direct IO 還限制讀寫必須是底層存儲設備塊大小的整數(shù)倍(甚至 Linux 2.4 還要求是文件系統(tǒng)邏輯塊的整數(shù)倍)。


所以接口越來越底層,換來表面上的效率提升的背后,需要在應用程序這一層做更多的事情。所以想用好這些高級特性,除了深刻理解其背后的機制之外,也要在系統(tǒng)設計上下一番功夫。


I/O Buffering

如圖,當程序調用各類文件操作函數(shù)后,用戶數(shù)據(jù)(User Data)到達磁盤(Disk)的流程如圖所示。


圖中描述了 Linux 下文件操作函數(shù)的層級關系和內存緩存層的存在位置。中間的黑色實線是用戶態(tài)和內核態(tài)的分界線。


從上往下分析這張圖:


1. 首先是 C 語言 stdio 庫定義的相關文件操作函數(shù),這些都是用戶態(tài)實現(xiàn)的跨平臺封裝函數(shù)。stdio 中實現(xiàn)的文件操作函數(shù)有自己的 stdio buffer,這是在用戶態(tài)實現(xiàn)的緩存。此處使用緩存的原因很簡單 — 系統(tǒng)調用總是昂貴的。如果用戶代碼以較小的 size 不斷的讀或寫文件的話,stdio 庫將多次的讀或者寫操作通過 buffer 進行聚合是可以提高程序運行效率的。


stdio 庫同時也支持 fflush 函數(shù)來主動的刷新 buffer,主動的調用底層的系統(tǒng)調用立即更新 buffer 里的數(shù)據(jù)。特別地,setbuf 函數(shù)可以對 stdio 庫的用戶態(tài) buffer 進行設置,甚至取消 buffer 的使用。


2. 系統(tǒng)調用的 read/write 和真實的磁盤讀寫之間也存在一層 buffer,這里用術語 Kernel buffer cache 來指代這一層緩存。在 Linux 下,文件的緩存習慣性的稱之為 Page Cache,而更低一級的設備的緩存稱之為 Buffer Cache。


這兩個概念很容易混淆,這里簡單的介紹下概念上的區(qū)別:Page Cache 用于緩存文件的內容,和文件系統(tǒng)比較相關。文件的內容需要映射到實際的物理磁盤,這種映射關系由文件系統(tǒng)來完成;Buffer Cache 用于緩存存儲設備塊(比如磁盤扇區(qū))的數(shù)據(jù),而不關心是否有文件系統(tǒng)的存在(文件系統(tǒng)的元數(shù)據(jù)緩存在 Buffer Cache 中)。


作者:范桂颶 整理:極客重生


https://is-cloud.blog.csdn.net/article/details/105897963


- EOF -


本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉