本節書摘來自華章出版社《深入淺出dpdk》一書中的第2章,第2.8節時代背景,作者朱河清,梁存銘,胡雪焜,曹水 等,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
2.8 ddio
2.8.1 時代背景
當今時代,随着大資料和雲計算的爆炸式增長,寬帶的普及以及個人終端網絡資料的日益提高,對電信服務節點和資料中心的資料交換能力和網絡帶寬提出了更高的要求。并且,資料中心本身對虛拟化功能的需求也增加了更多的網絡帶寬需求。電信服務節點和資料中心為了應付這種需求,需要對内部的各種伺服器資源進行更新。在這種環境下,英特爾公司提出了intel? ddio(data direct i/o)的技術。該技術的主要目的就是讓伺服器能更快處理網絡接口的資料,提高系統整體的吞吐率,降低延遲,同時減少能源的消耗。但是,ddio是如何做到這種優化和改進的呢?為了回答這個問題,有必要回顧一下ddio技術出現之前,伺服器是如何處理從網絡上來的資料的。
當一個網絡封包送到伺服器的網卡時,網卡通過外部總線(比如pci總線)把資料和封包描述符送到記憶體。接着,cpu從記憶體讀取資料到cache進而到寄存器。進行處理之後,再寫回到cache,并最終送到記憶體中。最後,網卡讀取記憶體資料,經過外部總線送到網卡内部,最終通過網絡接口發送出去。
可以看出,對于一個資料封包,cpu和網卡需要多次通路記憶體。而記憶體相對cpu來講是一個非常慢速的部件。cpu需要等待數百個周期才能拿到資料,在這過程中,cpu什麼也做不了。
ddio技術是如何改進的呢?這種技術使外部網卡和cpu通過llc cache直接交換資料,繞過了記憶體這個相對慢速的部件。這樣,就增加了cpu處理網絡封包的速度(減少了cpu和網卡等待記憶體的時間),減小了網絡封包在伺服器端的處理延遲。這樣做也帶來了一個問題,因為網絡封包直接存儲在llc cache中,這大大增加了對其容量的需求,因而在英特爾的e5處理器系列産品中,把llc cache的容量提高到了20mb。
圖2-11是ddio技術對網絡封包的處理流程示意圖。

ddio功能子產品會學習來自i/o裝置的讀寫請求,也就是i/o對記憶體的讀或者寫的請求。例如,當網卡需要從伺服器端傳送一個資料封包到網絡上時,它會發起一個i/o讀請求(讀資料操作),請求把記憶體中的某個資料塊通過外部總線送到網卡上;當網卡從網絡中收到一個資料封包時,它會發起一個i/o寫請求(寫資料操作),請求把某個資料塊通過外部總線送到記憶體中某個位址上。
接下來的章節會詳細介紹在沒有ddio技術和有ddio技術條件下,伺服器是如何處理這些i/o讀寫請求的。
2.8.2 網卡的讀資料操作
通常來說,為了發送一個資料封包到網絡上去,首先是運作在cpu上的軟體配置設定了一段記憶體,然後把這段記憶體讀取到cpu内部,更新資料,并且填充相應的封包描述符(網卡會通過讀取描述符了解封包的相應資訊),然後寫回到記憶體中,通知網卡,最終網卡把資料讀回到内部,并且發送到網絡上去。但是,沒有ddio技術和有ddio技術條件的處理方式是不同的,圖2-12是兩種環境下的處理流程圖。
圖2-12a是沒有ddio技術的處理流程。
1)處理器更新封包和控制結構體。由于配置設定的緩沖區在記憶體中,是以會觸發一次cache不命中,處理器把記憶體讀取到cache中,然後更新控制結構體和封包資訊。之後通知nic來讀取封包。
2)nic收到有封包需要傳遞到網絡上的通知後,它首先需要讀取控制結構體進而知道從哪裡擷取封包。由于之前處理器剛把該緩沖區從記憶體讀到cache中并且做了更新,很有可能cache還沒有來得及把更新的内容寫回到記憶體中。是以,當nic發起一個對記憶體的讀請求時,很有可能這個請求會發送到cache系統中,cache系統會把資料寫回到記憶體中,然後記憶體控制器再把資料寫到pci總線上去。是以,一個讀記憶體的操作會産生多次記憶體的讀寫。
圖2-12b是有ddio技術的處理流程。
1)處理器更新封包和控制結構體。這個步驟和沒有ddio的技術類似,但是由于ddio的引入,處理器會開始就把記憶體中的緩沖區和控制結構體預取到cache,是以減少了記憶體讀的時間。
2)nic收到有封包需要傳遞到網絡上的通知後,通過pci總線把控制結構體和封包送到nic内部。利用ddio技術,i/o通路可以直接将cache的内容送到pci總線上。這樣,就減少了cache寫回時等待的時間。
由此可以看出,由于ddio技術的引入,網卡的讀操作減少了通路記憶體的次數,因而提高了通路效率,減少了封包轉發的延遲。在理想狀況下,nic和處理器無需通路記憶體,直接通過通路cache就可以完成更新資料,把資料送到nic内部,進而送到網絡上的所有操作。
2.8.3 網卡的寫資料操作
網卡的寫資料操作和上節講到的網卡的讀資料操作是完全相反的操作,通俗意義上來講就是有網絡封包需要送到系統内部進行處理,運作的軟體可以對收到的封包進行協定分析,如果有問題可以丢棄,也可以轉發出去。其過程一般是nic從網絡上收到封包後,通過pci總線把封包和相應的控制結構體送到預先配置設定的記憶體,然後通知相應的驅動程式或者軟體來處理。和之前講到的網卡的讀資料操作類似,有ddio技術和沒有ddio技術的處理也是不一樣的,以下是具體處理過程。
首先還是沒有ddio技術的處理流程,如圖2-13a所示。
1)封包和控制結構體通過pci總線送到指定的記憶體中。如果該記憶體恰好緩存在cache中(有可能之前處理器有對該記憶體進行過讀寫操作),則需要等待cache把内容先寫回到記憶體中,然後才能把封包和控制結構體寫到記憶體中。
2)運作在處理器上的驅動程式或者軟體得到通知收到新封包,去記憶體中讀取控制結構體和相應的封包,cache不命中。之是以cache一定不會命中,是因為即使該記憶體位址在cache中,在步驟1中也被強制寫回到記憶體中。是以,隻能從記憶體中讀取控制結構體和封包。
有ddio技術的處理流程,如圖2-13b所示。
1)這時,封包和控制結構體通過pci總線直接送到cache中。這時有兩種情形:
2)運作在處理器上的驅動或者軟體被通知到有封包到達,其産生一個記憶體讀操作,由于該内容已經在cache中,是以直接從cache中讀。
由此可以看出,ddio技術在處理器和外設之間交換資料時,減少了處理器和外設通路記憶體的次數,也減少了cache寫回的等待,提高了系統的吞吐率和資料的交換延遲