"點我查看秘籍連載" I/O操作和DMA、RDMA 用戶進程想要執行IO操作時(例如想要讀磁碟數據、向磁碟寫數據、讀鍵盤的輸入等等),由於用戶進程工作在用戶模式下,它沒有執行這些操作的許可權,只能通過發起對應的系統調用請求操作系統幫忙完成這些操作。這裡因為系統調用產生中斷將陷入到內核,進行一次上下文切 ...
I/O操作和DMA、RDMA
用戶進程想要執行IO操作時(例如想要讀磁碟數據、向磁碟寫數據、讀鍵盤的輸入等等),由於用戶進程工作在用戶模式下,它沒有執行這些操作的許可權,只能通過發起對應的系統調用請求操作系統幫忙完成這些操作。這裡因為系統調用產生中斷將陷入到內核,進行一次上下文切換操作。
內核進程幫忙執行IO操作時,由於IO操作相比於CPU來說是極慢的操作,CPU不應該等待在這個過程中,而是切換到其它進程上去執行其它任務。這裡再次涉及到一次上下文切換:從內核態回到用戶態的其它進程。
DMA要求硬體的支持,需要在硬體中集成一個小型的“CPU”,比如現在的機械硬碟、固態硬碟、網卡等硬體都帶有DMA功能,這樣操作系統要執行IO操作時,直接將相關指令發送給這些DMA硬體,DMA處理器負責IO操作,而操作系統這時可以放棄CPU,讓CPU去執行其它進程。例如對於讀磁碟文件時,操作系統將相關指令以及數據應寫在哪個記憶體地址發送給DMA硬體後,由DMA硬體去讀寫數據到指定記憶體地址,當IO操作完成後,DMA硬體通過匯流排發送一個硬體中斷給CPU,於是陷入到內核態(這裡涉及了一次上下文切換),內核就知道了IO已經完成,於是將Kernel Buffer數據拷貝到用戶進程的IO Buffer,並準備調度用戶進程(再次上下文切換)。
假如不使用DMA硬體的話,那麼IO操作過程中,操作系統將多次參與,負責將硬體數據讀入或讀出記憶體,操作系統參與意味著要陷入到內核態,並且獲取CPU控制權,這也意味著要進行大量的上下文切換以及占用大量CPU資源。
而使用DMA後,只有4次必要的上下文切換,且IO操作的過程中完全不需要消耗CPU資源。
除了DMA,還有更高級的RDMA(Remote Direct Memory Access)機制,它需要操作系統和硬體的支持,還需要編寫RDMA方式的代碼。
前面介紹緩衝空間時提到過,一般情況下,每個用戶進程要讀、寫數據,都會經過兩個必要的緩衝層:內核空間的Kernel Buffer、用戶空間的IO Buffer。例如讀文件數據時,先將數據拷貝到內核的緩衝空間(page cache),然後陷入內核,內核將該緩衝空間數據拷貝到用戶空間的緩衝空間(IO Buffer),當調度到用戶進程時,用戶進程從自己的緩衝空間讀取數據。
DMA機制並沒有繞過這兩個緩衝層,但使用RDMA機制,程式可以直接繞過Kernel Buffer,內核發現是RDMA操作後,直接告訴RDMA硬體將讀取的數據(寫操作也一樣)寫入到用戶空間的IO Buffer,而不需要先拷貝到Kernel Buffer,再拷貝到IO Buffer。雖然RDMA機制相比DMA不會減少上下文切換次數,但是它減少了記憶體數據拷貝的過程,相當於是使用了O_DIRECT標記的直接IO技術。
DMA和RDMA兩種技術對比如圖:RDMA一般實現在網卡上,但出於方便理解,下圖直接使用磁碟來描述
像這種繞過內核功能的技術,通常稱為內核旁路(Kernel Bypass),RDMA技術內核旁路的是一種,還有像TOE也是內核旁路的一種。
雖然RDMA比較優秀,但是它需要硬體、操作系統和代碼的同時支持,對編程而言是一個比較大的衝擊,所以目前使用的非常少。