??? 摘 要: FAT32在Linux上的優化與實現是提高硬盤式嵌入式設備性能的關鍵因素。通過深入分析FAT32文件系統" title="文件系統">文件系統在Linux上的實現細節,針對性地提出了多種優化策略:Block機制實現優化、預讀機制控制優化、Page機制改進等。最后給出了一個實際系統的性能優化比較。
??? 關鍵詞: Linux? FAT32文件系統? 預讀? 優化
?
??? 隨著芯片技術的發展,各種處理器的處理能力" title="處理能力">處理能力不斷提高,手持智能終端得到極大的普及。嵌入式Linux操作系統在未來的手持智能設備" title="智能設備">智能設備中將扮演著非常重要的角色,使嵌入式Linux的應用和研究不斷的深入。
由于Microsoft公司的Windows操作系統占據了桌面操作系統絕大多數份額,而手持智能設備與PC機的數據交換又在所難免,因此,絕大多數的大容量" title="大容量">大容量嵌入式智能設備必須采用與PC機兼容的FAT/FAT32文件系統。隨著便攜式硬盤的應用,FAT32在嵌入式硬盤上已成為主流的格式。
??? 同時,隨著CPU處理能力的提高,面向存儲的應用需求在手持智能設備上也隨著不斷增長,文件系統的訪問性能將是未來的手持設備非常關鍵的因素。然而,當硬盤在手持智能設備上應用時,由于硬盤訪問的高耗能特性,對于手持設備的設計構成了極大的挑戰。而硬盤的能耗又與讀寫訪問的時間成正比,從節能的角度出發,系統設計者同樣希望在單位時間內讀取更多內容,以減少硬盤訪問時間從而達到節能的目的。因此,在Linux上的FAT32的優化實現成為非常迫切的需求。
1 Linux中FAT32文件系統讀操作分析
1.1 虛擬文件系統與FAT32[1-2]
??? Linux系統中的虛擬文件系統VFS(Virtual File System)是一個非常強大的機制,其設計思路是在內核中提供一個文件系統框架,包括接口函數集、管理用的數據結構以及各種緩存機制。VFS提供上下兩個方面的接口,上層接口是提供給I/O系統的用戶使用的,包括應用程序和內核的其他管理模塊,通過該接口可使I/O系統(文件、設備、網絡等)完成如打開、關閉、讀、寫等;下層接口是提供給真實文件系統的,VFS支持的每個真實文件系統都要通過這個接口來實現。通過這種機制,Linux將系統存在的各種真實文件系統(如EXT2/EXT3、FAT/FAT32、JFFS/JFFS2等)以及設備文件都統一到一種操作中,以此來實現系統的管理與調度。
??? FAT(File Allocation Table)文件系統是Microsoft公司推出的廣泛使用在Dos、Windows 9X、Windows 2000以及Windows XP系統中。由于Windows系列的操作系統的普及,其FAT文件系統被人們所廣泛熟悉和應用。當前針對大容量硬盤,FAT32文件系統占據了主要的地位。在FAT32文件系統中,以下三個概念與文件的組織密切相關:
??? 扇區(Sector): 數據存取的最小物理單位。
??? 簇(Cluster):文件最小分配單位,與分區大小、文件系統相關。
??? 邏輯扇區(Logic Sector):在文件系統實現中,為了優化和統一設計所定義的讀寫長度。
1.2 文件讀在內核中的實現
??? 以讀操作為例,通過Linux系統中VFS的作用,從用戶空間對FAT32的操作,系統可以抽象成從fread( )映射到內核函數do_generic_file_read( )來完成具體的文件讀操作。在文件/μCLinux/linux-2.4.x/mmnommu/filemap.c中存在這個接口實現的原型。雖然這類接口并不是基本的,但正如大多數文件系統的實現,FAT32就是通過這類接口來實現文件的各種操作。
??? 圖1描述了函數do_generic_file_read( )的實現原理。從函數入口處獲得目標內容的文件描述指針,從而獲得文件入口。通過分析描述符inode以及當前狀態,系統獲得預讀read_ahead的大小,進行相應的計算,獲得所需要獲取的目標內容Page頁索引以及offset偏移量。然后發起預讀的指令,并等待獲得相應的Page內容后,將其拷貝到buffer中進行組織,并提供上層程序磁盤文件在內存中的映像。
??????????????????????????
1.3 文件預讀機制與Page讀[1-4]
??? 在do_generic_file_read的實現中,磁盤讀動作實際是在預讀read_ahead中完成的,即預讀機制。這是由于Linux系統為了獲得更高的性能以及充分利用CPU處理能力,VFS設計中做了一層buffer/cache緩沖。當系統發現buffer/cache中有即將要訪問的內容缺失時,系統將發起一次預讀請求。下層文件系統根據尋找CPU以及總線的空閑狀態,執行具體的預讀機制。這樣,上下層構成一個異步過程來完成系統的任務,以達到充分利用系統資源的目的。
??? 在考察read_ahead( )的實現中可以發現,實際上read_ahead( )函數的主要功能是根據實際需求不斷調用文件系統中的readpage( )函數來完成的。這是由于Linux的內存管理都是按照頁(Page)模式進行組織的。也就是說,每次從具體的對象數據存儲設備(如硬盤)上讀取相應的數據時,將嚴格按照page的大小進行讀取動作。根據一般定義,Page采用4 096B為單位。在Linux上的FAT32實現中,將由fat_readpage( )具體應用實例來實現這個功能。
1.4 Block讀實現[3-4]
??? 由于不同的硬件設備存在不同的物理結構,在文件系統格式化時,最基本的存儲單元Cluster的大小是不同的。如通常能夠見到的有512B、1KB等。也就是說,實際文件的存儲是按照不同的目標存儲設備劃分為不同的塊來存儲的。在文件系統實現中,為了兼容不同的目標系統與硬件設備,在FAT文件系統中的Page讀動作的實現中,引入了一個Block概念,即根據具體文件描述,按照Block大小完成整個Page的讀命令。
???? 在μCLinux/linux-2.4.x/mmnommu/filemap.c文件中,fat_readpage( )的實現就是根據上述目標進行相應設計的,即通過inode獲取相應文件的具體存儲信息,然后將Page讀轉化為按照Block塊方式進行讀操作。也就是通過反復調用block_read_full_page( )函數來滿足最后Page內容的獲取。
??? 函數block_read_full_page( )的具體實現過程如圖2所示。系統根據傳入的參數,獲得Block大小,生成相應的緩存空間,然后反復發出Block讀的Request,直到完成整個Page的讀任務。
???????????????????????????
??? 如圖2所示Block_read_full_page( )的實現機理中,最重要的是根據系統狀況,經過計算確切地獲得將由多少個Block來組成一個Page。
??? 在Linux實現中,Block大小決定于文件描述符inode中的i_blkbits域。在Linux中的FAT32文件系統設計中,inode->i_blkbits是由FAT32系統中的logic_sector_size決定的,即用/linux-2.4.x/fs/fat/inode.c來實現從FAT32文件系統映射到Linux的inode各項定義。
1.5 系統MAKE_REQUEST[1-4]
??? 經過上述各個步驟的計算,在文件系統實現中,將文件讀操作轉化為若干個不同的Block讀需求,最后向下層驅動程序層發起具體的命令Request。上述的轉化,基本上是根據底層配置以及內存管理的需求,將大的/整體的命令細分/拆分為更加細小的動作。
??? 而在實際執行過程中,肯定存在較多的過度拆分的情況,以致于產生過多低效率的命令,因此,在具體實現過程中,為了避免這種情況,在實際發出Request之前,需要對其進行相應的檢查,合并相關的Request,以提高系統實現性能。這個過程將由submit_bh來完成。
??? 圖3所示是submit_bh函數中的主體調用子函數_make_request的實現過程。在FAT32實現中,_make_request根據獲得的Block大小、存儲設備的sector number,準備好內存空間后,向IDE發出具體的Request。而具體的Request合并將發生在發出Request之前。其實現原理根據當前隊列中Request的地址相關性來判斷。
??????????????????????
2 優化策略分析
??? 面對提高文件系統訪問性能的需求,經過分析系統如何處理用戶發起的讀命令,觀察read( )命令從VFS到具體的文件系統FAT32的實現,轉化為具體的每一個Request的整個過程,系統的優化可從以下幾個方面進行。
2.1 Block讀操作改進
??? 根據1.4節針對block_read_full_page( )的描述,實際上是根據實際文件系統定義的Block大小,將一個page轉化為多個Block的讀動作。而在FAT32的具體實現中,根據/linux-2.4.x/fs/fat/inode.c文件中的描述,Block size等于logic_sector_size的大小,即邏輯扇區大小。
??? 在FAT文件系統的定義中,邏輯扇區是為了統一不同硬盤的物理扇區而設置的。由于一般物理扇區最小為512B,因此在FAT32普遍實現中,邏輯扇區設置為512B。
??? 而當前大容量的硬盤系統,其物理扇區普遍大于4KB。在這種情形下,根據Linux上的FAT32實現,一個4KB或者以上的物理扇區的讀,被人為地劃分為8次512B邏輯扇區的讀命令。而由于物理原因,可知道物理扇區將是磁盤上最小的尋址單位,也就是說,在最壞的情況下(即下層__make_request沒有及時判斷出這些buffer是可以合并的),向一個以4KB為扇區的硬盤發出一個page(4KB)的讀命令,最后將由8次同一個扇區的讀動作來實現。
??? 針對block_read_full_page劃分的不合理,可以嘗試用重寫block_read_full_page來實現,即擴大Block為4KB。這樣即可以認為,一個Linux的page讀將按照一次Block讀來完成。同時由于Linux內存管理都以4KB大小的page作為基本單位,這樣在所有文件系統的內部,將以4KB為最小單位進行讀取,把跨4KB的特殊情況留給下層驅動來完成拆分(由于大容量硬盤的應用目標,這種情況幾乎不會出現)。因此,Block改進就是通過改進Block的大小,進行合并過多的拆分,來達到提高系統的讀性能的作用。
2.2 預讀機制控制
??? Linux系統上的FAT32文件系統實現,依然強烈依賴著預讀機制來完成實際的讀操作。這是由于Linux最初是以PC機為設計目標的,即存在內存交換文件和各種緩沖機制來對有限的資源進行無限的邏輯擴展[5]。
??? 這種多重緩沖的設計機制,非常適合應用程序/控制命令流存儲的磁盤管理。然而,在本嵌入式系統" title="嵌入式系統">嵌入式系統設計中,FAT32作為數據存儲空間,數據存儲相對有序,并且可預測性比較強。因此,這種抽象帶來的好處不是特別的明顯。同時由于存在多級緩沖,尤其是硬盤系統的多級緩沖,會造成以下幾個缺點:
??? (1)因多次數據搬移,造成性能下降。對于嵌入式系統尤其是消費類設備,由于成本的原因,其總線帶寬(包括內存總線與外部總線)都是相對有限的,因此,在這類總線中的數據搬移造成的延遲,是不能忽略的(而PC機的設計中,由于高速的內存吞吐量,往往這個延遲是可以忽略的)。
??? (2)緩沖和cache的存在,會造成具體動作更多不可預測性,這違反了實時系統的需求。因為嵌入式系統很多層面都有一定的實時性要求;其次,增加了硬盤電源管理的難度,即硬盤狀態將頻繁切換,減少有機會進入省電的Idle模式及更加省電的Sleep模式,浪費了硬盤自身APM(Advanced Power Management)帶來的好處。
??? 因此,在本設計中需要對預讀機制進行管理,甚至去除預讀機制。實際上是對文件讀實現中的do_generic_file_read( )函數進行改造,去除了預讀判斷機制,采用直接調用方式。
2.3 Page機制改進
??? 整個文件系統的讀操作,將以page為單位進行相應的規劃,即以4 096B為考慮對象。而在真實的磁盤系統中,由于大容量磁盤的普及,4 096B幾乎成了最小的物理扇區。面對這樣的磁盤系統,其FAT文件讀寫具體實現,實際上不能充分利用底層硬件以及驅動程序提供的各種優化措施,如DMA等[6-7]。
??? 針對這樣的思路,需要引入多個page讀操作的相關性,即在fat_readpage( )之前增加多個page合并的判斷。可以借鑒Request合并的方式進行page合并,即通過目標地址判斷的方式進行合并部分Page讀動作。
3 優化實例
??? 在實際優化中,采用了前面提到的三種優化策略,在某一個實際的系統上進行相應的測試,取得了較好的效果。
??? 圖4是一個ARM嵌入式系統的詳細測試結果。該測試的物理實施條件是:
????????????????????
??? ARM7TDMI的系統,CPU頻率88MHz,8KB i-cache/no d-cache;硬盤掛接的EMIF為44MHz,16bit位寬;SDRAM為32bit位寬,運行在88MHz下;硬盤為4 200轉,20GB;系統采用μCLinux 2.4.18。
測試采用發起read( )用戶讀操作進行相應的測試。其中每個測試采用不同大小的buffer來觀察實際優化前/后的訪問速率比較。
??? 從測試結果可以看出,在采用buffer為8KB進行文件讀時,可以取得超過50%以上的訪問性能的提升。同時在這種測試條件下,也獲得了最好的讀性能,達到2MB/s以上的測試性能。這個讀性能基本上已可以滿足很多多媒體系統所需要的數據流要求。
??? 同時在這種優化策略下,應用系統可以有針對性地優化應用程序中的各種讀操作。建議采用4KB或者8KB的buffer,使系統運行在最佳的狀態。
??? 本文仔細分析了Linux的FAT32實現中讀操作的具體實現過程,針對FAT32系統實現的缺陷,提出了多種優化策略,并在某一個嵌入式設備中進行具體的優化和測試,取得了一定的性能提升。最后給出了對應用程序設計的建議。
??? 文件系統優化是一個非常深奧的課題,尤其是嵌入式系統的文件系統設計,針對不同的應用,應有不同的優化目標。本文介紹了初步的優化方法,在某一個具體的嵌入式設備上進行相應的實踐,取得了良好的效果。
參考文獻
[1] 毛德操,胡希明. Linux內核情景分析[M]. 杭州: 浙江大學出版社, 2001.
[2]?郭玉東. Linux操作系統結構分析[M].西安:西安電子科技大學出版社,2002.
[3]?WILLIAM D R, HEYBRUCK F. An introduce to FAT 16/FAT?32 file systems. Hitachi Global Storage Technologies,Charlotte, NC. 2005.
[4]?張明亮,張宗杰. 淺析FAT32文件系統[J]. 計算機與數字工程,2005,33(1):56-59.
[5]?吳嫻. 嵌入式Linux文件系統的設計與實現[J].計算機工程與應用,2005,(9):111-112.
[6]?袁春旭,高飛.TMS320F206對基于FAT32文件系統IDE硬盤的文件操作[J].現代電子技術,2004,(6):88-91.
[7]?楊道良,任曉霞. Linux下連續媒體文件系統研究[J].計算機工程與應用,2000,(8):5-10.