與標準 I/O 系統呼叫相比,記憶體映射文件如何顯著提高性能?
作業系統概念說
**考慮使用標準系統呼叫 open()、read() 和 write()**順序讀取磁碟上的文件。每個文件訪問都需要係統呼叫和磁碟訪問。
或者,我們可以使用目前討論的虛擬記憶體技術將文件 I/O 視為例行記憶體訪問。這種方法稱為 記憶體映射文件,允許虛擬地址空間的一部分與文件進行邏輯關聯。正如我們將看到的,這可以顯著提高性能. 記憶體映射文件是通過將磁碟塊映射到記憶體中的一個(或多個頁面)來完成的。對文件的初始訪問通過普通的請求分頁進行,從而導致頁面錯誤。但是,文件的頁面大小部分從文件系統讀取到物理頁面中(某些系統可能選擇一次讀取超過頁面大小的記憶體塊)。對文件的後續讀取和寫入將作為例行記憶體訪問處理。通過記憶體操作文件而不是產生使用 read() 和 write() 系統呼叫的成本,簡化並加快了文件訪問和使用。
你能分析一下記憶體映射文件的性能嗎?
如果我是正確的,記憶體映射文件的工作方式如下。創建記憶體映射需要係統呼叫。然後當它訪問映射的記憶體時,就會發生頁面錯誤。頁面錯誤也有成本。
與標準 I/O 系統呼叫相比,記憶體映射文件如何顯著提高性能?
謝謝。
記憶體映射文件直接避免了複製緩衝區,這發生在
read()
和write()
呼叫中。呼叫read()
並write()
包含指向儲存數據的程序地址空間中的緩衝區的指針。核心必須將數據複製到/從這些位置。使用mmap()
將文件映射到程序的地址空間,因此程序可以直接定址文件而無需副本。如果文件在初始時載入到記憶體,則在初始呼叫之後訪問記憶體映射文件時也沒有系統呼叫成本
mmap()
。如果映射文件的某個頁面不在記憶體中,訪問將產生錯誤並要求核心將該頁面載入到記憶體中。讀取大塊read()
可以比mmap()
在這種情況下更快,如果mmap()
會產生大量錯誤來讀取文件。(可以提前通知核心,madvise()
以便核心可以在訪問之前提前載入頁面)。有關更多詳細資訊,請參閱 Stack Overflow 上的相關問題:mmap() vs. reading blocks