零拷貝詳解(上)

2021-10-03 01:51:04 字數 2001 閱讀 1128

拷貝也就是把磁碟或網路中的a檔案中拷到b檔案中。那麼是誰來執行從磁碟中讀取操作和寫入操作的呢,並且他們讀取完以後是直接就能拷到b檔案中,還是需要進行一些複雜的處理?在這裡將會對比下傳統的資料傳輸和零拷貝方式的傳輸,這兩者有什麼區別。

在這之前先了解使用者態和核心態這2個概念:

再然後讓我們了解下什麼是上下文切換以及為什麼上下文切換產生的開銷大會影響效能?

在每個任務執行前,cpu都需要知道任務從**載入,又是從**開始執行,也就是說,需要系統事先幫他設定好cpu暫存器程式計數器(program counter,pc)

cpu暫存器,是cpu內建的容量小、但速度極快的記憶體。程式計數器,則是用來儲存cpu正在執行的指令的位置,或者即將執行的下一條指令的位置。他們都是cpu在執行任何任務前,必須依賴的環境,因此也被叫做cpu上下文。

cpu上下文切換,就是先把前乙個任務的cpu上下文(也就是cpu暫存器和程式計數器)儲存起來,然後載入新任務的上下文,到這些暫存器和程式計數器,最後再跳轉到程式計數器所指的新位置,執行新任務。

其實cpu上下文切換分為三種,程序上下文切換、執行緒上下文切換、中斷上下文切換

在這裡我們主要說的是程序上下文切換中的系統呼叫程序的執行空間分為核心空間和使用者空間

因為使用者空間只能訪問有限資源,不能直接訪問記憶體等硬體裝置,必須通過系統呼叫深入核心才能訪問這些資源。

程序可以在這核心空間和使用者空間執行,分別稱為程序的使用者態和程序的核心態。

程序是由核心來管理和排程的,程序的切換只能發生在核心態。程序的上下文不僅包括了虛擬記憶體、棧、全域性變數等使用者空間的資源,還包括了核心堆疊、暫存器等核心空間的狀態。

從使用者態到核心態的轉變需要通過系統呼叫來完成,需要進行cpu上下文切換,儲存使用者態的cpu上下文,載入核心態的cpu上下文,結束後相反,其中發生了兩次cpu上下文切換。這一切都在同乙個程序中進行,會消耗系統資源,但並不是程序的cpu上下文切換。

程序的上下文切換比系統呼叫多一步,在儲存當前程序的核心狀態和cpu暫存器之前,需要先把該程序的虛擬記憶體和棧等儲存下來,而載入了下乙個程序的核心狀態和cpu暫存器之後,還需要重新整理下乙個程序的虛擬記憶體和棧等。

儲存cpu上下文和恢復cpu上下文是需要系統核心在cpu上執行才能完成的。所以程序上下文切換次數較多,很容易導致cpu將大量時間耗費在暫存器、核心棧以及虛擬記憶體等資源的儲存和恢復上,大大縮短了真正執行程序的時間。

當程序使用read()、write()去讀取和寫入磁碟中的檔案時會分為以下幾個步驟:

將程序的使用者態轉變為核心態(屬於系統呼叫,也是一次上下文切換,需要花費cpu時間

核心態程序讀取磁碟檔案內容放到核心空間中,然後把核心空間中的檔案拷貝到使用者空間中。(第一次記憶體拷貝

然後把核心態裝變為使用者態(第二次上下文切換

程序將資料輸入到使用者空間中,然後將程序的使用者態轉變為核心態(第三次上下文切換

核心態下程序讀取使用者空間下的資料拷貝到核心空間中(第二次記憶體拷貝

核心空間中資料寫入到磁碟空間中,然後核心態轉變為使用者態(第四次上下文切換

可見傳統的傳輸過程中會發生4次上下文切換,2次的記憶體拷貝。很消耗cpu時間和記憶體空間。到此為止,我們就了解為什麼傳統io是那麼的消耗效能且效率又低的原因了。

零拷貝原理詳解

在nginx kafka等開源元件的原理和效能調優中,經常會提到零拷貝技術,為了能從原理層面掌握這些常用元件,下面我詳細介紹零拷貝的原理。在介紹零拷貝之前,還有幾個概念需要介紹,那就是 使用者空間 user space 核心空間 kernel space 使用者空間是指 使用者程式 執行的地方 核心...

sendfile 實現零拷貝詳解

2013年11月18日 11 17 供稿中心 網際網路運營部 摘要 linux的sendfile 系統呼叫 伺服器響應乙個http請求的步驟如下 1 把磁碟檔案讀入核心緩衝區 2 從核心緩衝區讀到記憶體 3 處理 靜態資源不需處理 4 傳送到網絡卡的核心緩衝區 傳送快取 5 網絡卡傳送資料 資料從第...

零拷貝問題

零拷貝 定義 避免cpu將資料從一塊儲存空間拷貝到另乙個儲存空間的技術。通常用於網路檔案傳輸 以減少cpu消耗和記憶體頻寬的占用 減少使用者空間 使用者可操作的記憶體快取區域 和cpu核心空間 cpu核心可操作的記憶體快取和暫存器快取 的拷貝過程,減少使用者上下文和cpu核心上下文的切換,讓cpu解...