mmap爲何比read/write快(兼論buffercache和pagecache)

參考文獻:html

從內核文件系統看文件讀寫過程》http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool&utm_medium=referralnode

 

《mmap是什麼》http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool&utm_medium=referrallinux

 

正文:算法

 

      首先說一下文件系統,Linux文件系統的三層結構想必你們多少都瞭解一些,每一個進程中都有一個用戶文件描述符表,表項指向一個全局的文件表中的某個表項,文件表表項有一個指向內存inode的指針,每一個inode惟一標識一個文件。若是同時有多個進程打開同一文件,他們的用戶文件描述符表項指向不一樣的文件表項,可是這些文件表項會指向同一個inode。緩存

 

     此時又會引出另一個東東:page cache。內核會爲每一個文件單獨維護一個page cache,用戶進程對於文件的大多數讀寫操做會直接做用到page cache上,內核會選擇在適當的時候將page cache中的內容寫到磁盤上(固然咱們能夠手工fsync控制回寫),這樣能夠大大減小磁盤的訪問次數,從而提升性能。Page cache是linux內核文件訪問過程當中很重要的數據結構,page cache中會保存用戶進程訪問過得該文件的內容,這些內容以頁爲單位保存在內存中,當用戶須要訪問文件中的某個偏移量上的數據時,內核會以偏移量爲索引,找到相應的內存頁,若是該頁沒有讀入內存,則須要訪問磁盤讀取數據。爲了提升頁得查詢速度同時節省page cache數據結構佔用的內存,linux內核使用樹來保存page cache中的頁。安全

 

     在瞭解了以上的基礎以後,咱們就來比較一下mmap和read/write的區別,先說一下read/write系統調用,read/write系統調用會有如下的操做:數據結構

 

  1. 訪問文件,這涉及到用戶態到內核態的轉換
  2. 讀取硬盤文件中的對應數據,內核會採用預讀的方式,好比咱們須要訪問100字節,內核實際會將按照4KB(內存頁的大小)存儲在page cache中
  3. 將read中須要的數據,從page cache中拷貝到用戶緩衝區中

 

     整個過程仍是比較艱辛的,基本上涉及到用戶內核態的切換,還有就是數據拷貝接下來繼續說mmap吧,mmap系統調用是將硬盤文件映射到用內存中,說的底層一些是將page cache中的頁直接映射到用戶進程地址空間中,從而進程能夠直接訪問自身地址空間的虛擬地址來訪問page cache中的頁,這樣會並涉及page cache到用戶緩衝區之間的拷貝,mmap系統調用與read/write調用的區別在於:post

 

  1. mmap只須要一次系統調用,後續操做不須要系統調用
  2. 訪問的數據不須要在page cache和用戶緩衝區之間拷貝

 

     從上所述,當頻繁對一個文件進行讀取操做時,mmap會比read高效一些。性能

 

     最後再說一下page cache的話題,從上面所說咱們從磁盤文件中讀取的內容都會存在page cache中,但當咱們關閉這個文件時,page cache中內容會立馬釋放掉嗎?答案是否,磁盤的讀取速度比內存慢太多,若是能命中page cache能夠顯著提高性能,萬一後續又有對這個文件的操做,系統就能夠很快速的響應。固然,這些文件內容也不是一直存在page cache中的,通常只要系統有空閒物理內存,內核都會拿來當緩存使用,但當物理內存不夠用,內存會清理出部分page cache應急,這也就是告訴咱們程序對於物理內存的使用能省則省,交給內核使用,做用很大。ui

 

     還有就是普通的write調用只是將數據寫到page cache中,並將其標記爲dirty就返回了,磁盤I/O一般不會當即執行,這樣作的好處是減小磁盤的回寫次數,提供吞吐率,不足就是機器一旦意外掛掉,page cache中的數據就會丟失。通常安全性比較高的程序會在每次write以後,調用fsync當即將page cache中的內容回寫到磁盤中。

相關文章
相關標籤/搜索