前幾天師兄問了一個問題,一個程式,需要讀入檔案,它第一次執行時間和第二次執行時間一樣嗎?将檔案改名後呢,umount檔案系統後再mount上呢?
這裡實際上涉及到buffer cache ,page cache兩個概念。
先解釋一下
buffer cache 也叫塊緩沖,是對實體磁盤上的一個磁盤塊進行的緩沖,其大小為通常為1k,磁盤塊也是磁盤的組織機關。設立buffer cache的目的是為在程式多次通路同一磁盤塊時,減少通路時間。系統将磁盤塊首先讀入buffer cache 如果cache空間不夠時,會通過一定的政策将一些過時或多次未被通路的buffer cache清空。程式在下一次通路磁盤時首先檢視是否在buffer cache找到所需塊,命中可減少通路磁盤時間。不命中時需重新讀入buffer cache。對buffer cache 的寫分為兩種,一是直接寫,這是程式在寫buffer cache後也寫磁盤,要讀時從buffer cache 上讀,二是背景寫,程式在寫完buffer cache 後并不立即寫磁盤,因為有可能程式在很短時間内又需要寫檔案,如果直接寫,就需多次寫磁盤了。這樣效率很低,而是過一段時間後由背景寫,減少了多次訪磁盤 的時間。
buffer cache 是由實體記憶體配置設定,linux系統為提高記憶體使用率,會将空閑記憶體全分給buffer cache ,當其他程式需要更多記憶體時,系統會減少cahce大小,
page cache 也叫頁緩沖或檔案緩沖,是由好幾個磁盤塊構成,大小通常為4k,在64位系統上為8k,構成的幾個磁盤塊在實體磁盤上不一定連續,檔案的組織機關為一頁, 也就是一個page cache大小,檔案讀取是由外存上不連續的幾個磁盤塊,到buffer cache,然後組成page cache,然後供給應用程式。
page cache在linux讀寫檔案時,它用于緩存檔案的邏輯内容,進而加快對磁盤上映像和資料的通路。具體說是加速對檔案内容的通路,buffer cache緩存檔案的具體内容——實體磁盤上的磁盤塊,這是加速對磁盤的通路。
swap space 交換空間,是虛拟記憶體的表現形式。系統為了應付一些需要大量記憶體的應用,而将磁盤上的空間做記憶體使用,當實體記憶體不夠用時,将其中一些暫時不需的資料交換 到交換空間,也叫交換檔案或頁面檔案中。做虛拟記憶體的好處是讓程序以為好像可以通路整個系統實體記憶體。因為在一個程序通路資料時,其他程序的資料會被交換 到交換空間中。
現在來分析問題,程式第一次執行時,讀取檔案過程,從磁盤讀取到buffer cache 到page cache再到應用程式的程序空間。第二次執行時由于buffer cache中已經有了部分或全部的檔案内容,這樣執行時間就要減少些。當然這也要視情景而定,具體有很多。當檔案改名後,其資料的實體位址未變,程式執行 時通過檔案指針仍能在記憶體上找到正确資料是以執行時間應該和第二次相同,但是umount檔案系統後,這些buffer cache 和page cache資訊應該會删除,因為若重新挂載另一檔案系統時,同樣的檔案名可能不對應同一個檔案,是以這時執行時間應該和第一次一樣。(個人看法,待修正)
linux中,應用程式通路檔案也就是核心通路page cache的API有兩種方式,1.通過VFS直接在不同檔案的Cache之間或者Cache與應用程式所提供的使用者空間buffer之間拷貝資料,其實作原理如圖7所示。
2,是通過VMM(虛拟記憶體管理)将Cache項映射到使用者空間,使得應用程式可以像使用記憶體指針一樣通路檔案,Memory map通路Cache的方式在核心中是采用請求頁面機制實作的,其工作過程如圖8所示。
首先,應用程式調用mmap(圖中1),陷入到核心中後調用do_mmap_pgoff(圖中2)。該函數從應用程式的位址空間中配置設定一段區域作為映射的 記憶體位址,并使用一個VMA(vm_area_struct)結構代表該區域,之後就傳回到應用程式(圖中3)。當應用程式通路mmap所傳回的位址指針 時(圖中4),由于虛實映射尚未建立,會觸發缺頁中斷(圖中5)。之後系統會調用缺頁中斷處理函數(圖中6),在缺頁中斷處理函數中,核心通過相應區域的 VMA結構判斷出該區域屬于檔案映射,于是調用具體檔案系統的接口讀入相應的Page Cache項(圖中7、8、9),并填寫相應的虛實映射表。經過這些步驟之後,應用程式就可以正常通路相應的記憶體區域了。
總的通路圖如下。