直接記憶體存取(direct memory access)
假設你必須把一千個箱子從卡車搬進倉庫。用中斷驅動輸入輸出,經理(CPU)親自一次搬一個箱子,即使有搬運工每搬一箱就提醒一次。用直接記憶體存取,你雇一個搬運工,指著卡車和貨架說「把一千個全搬過去」,然後走開,等整件事做完才被拍一下肩膀。DMA 是一個硬體幫手——DMA 控制器——它自行在裝置與主記憶體之間搬移一整塊資料,而 CPU 去做別的工作。
具體來說,CPU 只設定 DMA 控制器一次:這是來源(或目的)裝置、這是要讀出或寫入的記憶體位址、這是位元組數。然後 CPU 就自由了。DMA 控制器和 CPU 輪流使用匯流排(這稱為週期竊取,因為它偶爾借用一些匯流排週期),直接在控制器的緩衝區與 RAM 之間運送位元組,每個位元組都不需要 CPU 的指令。只有在整塊都傳輸完成時,它才發出單一一次中斷說「完成了」。所以一次 64 KB 的磁碟讀取,只花掉 CPU 兩件事——設定這次傳輸,以及處理最後那一次中斷——而不必涉入全部 65536 個位元組。
為什麼重要:DMA 是讓高頻寬輸入輸出可行的關鍵。沒有它,複製一個大檔案或串流千兆位元網路流量,幾乎會耗盡整顆 CPU 去搬位元組。有了它,CPU 設定好後就退到一旁。誠實的提醒:DMA 會與 CPU 爭奪記憶體頻寬(匯流排是共用的),而且由於控制器直接寫進 RAM,那些位址必須被仔細檢查與保護——一個有臭蟲或惡意、又具 DMA 能力的裝置寫到錯誤的實體位址,是真實的安全疑慮,這正是現代系統加上 IOMMU 來監管裝置記憶體存取的原因。
要讀取一個 4 KB 的磁碟區塊:CPU 告訴 DMA 引擎「把這個區塊讀進實體位址 0x200000」,然後去執行別的程式碼。DMA 控制器自行把全部 4096 個位元組串流進 RAM,最後只發出一次中斷。
一次設定、一次最終中斷——是控制器而非 CPU 搬移每一個位元組。
DMA 並不讓 CPU 變快;它只是把 CPU 從逐位元組的複製中抽離。CPU 最後仍會被中斷一次,而裝置仍會爭奪共用的記憶體匯流排。