搜集整理了一些概念 :
writethough vs writeback1. writethoughwrite-through意思是寫操作根本不使用緩衝。資料總是直接寫入磁碟。關閉寫緩衝,可釋放緩衝用於讀操作。(緩衝被讀寫操作共用)Write caching可以提高寫操作的效能。資料不是直接被寫入磁碟;而是寫入緩衝。從應用程式的角度看,比等待完成磁碟寫入操作要快的多。因此,可以提高寫效能。由控制器將緩衝內未寫入磁碟的資料寫入磁碟。表面上看,Write cache方式比write-through方式的讀、寫效能都要好,但是也要看磁碟訪問方式和磁碟負荷了。2. writebackwrite-back(write cache)方式通常在磁碟負荷較輕時速度更快。負荷重時,每當資料被寫入緩衝後,就要馬上再寫入磁碟以釋放緩衝來儲存將要寫入的新資料,這時如果資料直接寫入磁碟,控制器會以更快的速度運行。因此,負荷重時,將資料先寫入緩衝反而會降低輸送量。
cacheable vs buferfable1。對於Write-though的寫策略,Cacheable是回寫資料指是否要放進Cache(當然對於一些I/O操作等自然不能Cacheable了),Bufferable是指回寫資料可以放進WriteBuffer中,慢慢回寫僅主存(有些情況對於一些資料是要求立即寫回的,不能先buffer一下)2。對於Write-back的寫策略,同樣這樣解釋,但是一個例外就是Cacheable/unbufferable的情況,因為既然都Cache了,對於Write-back策略來說就意味著要等到Cache line被替換的時候才被寫入主存,這也就意味著寫回主存時間註定要被delay,所以一般它會被翻譯成Write-though cached/buffered的行為。
Starting && stopping cache flushing levels這兩個設定影響控制器如何處理未寫入磁碟的緩衝內資料,並且只在write-back cache方式下生效。緩衝內資料寫入磁碟稱為flushing.你可以配置Starting and stopping cache flushing levels值,這個值表示佔用整個緩衝大小的百分比。當緩衝內未寫入磁碟的資料達到starting flushing value時,控制器開始flushing(由緩衝寫入磁碟)。當緩衝內未寫入磁碟資料量低於stop flush value時,flushing過程停止。控制器總是先flush舊的快取資料。緩衝內未寫入資料停留超過20秒鐘後被自動flushing.典型的start flushing level是80%。通常情況下,stop flushing level也設定為80%。也就是說,控制器不允許超過80%的緩衝用於write-back cache,但還是儘可能保持這一比例。如果你使用此設定,可以在緩衝記憶體更多的未寫入資料。這有利於提高寫操作的效能,但是要犧牲資料保護。如果要得到資料保護,你可以使用較低的start and stop values。通過對這兩個參數的設定,你可以調整緩衝的讀、寫效能。經測試表明,使用接近的start and stop flushing levels時效能較好。如果stop level value遠遠低於start value,在flushing時會導致磁碟擁塞。
Cache block size這個值指緩衝配置單位大小,可以是4K或16K。選擇合適的值,可以明顯的改善緩衝使用效能。如果應用程式更多時候訪問小於8K的資料,而將cache block size設定為16K,每次訪問僅使用一部分cache block。在16K的cache block裡總是儲存8K或更小的資料,意味著只有50%的緩衝容量被有效使用,使效能下降。對於隨機I/O和小資料區塊的傳送,4K比較合適。另一方面,如果是連續I/O 並使用大的segment size,最好選擇16K。大的cache block size意味著cache block數量少並可縮短緩衝消耗延時。另外,對於同樣大小的資料,cache block size大一些,需要的快取資料傳送量更小。
dma_alloc_coherent vs dma_alloc_writecombine都是分配連續實體記憶體,返回虛擬位址1.dma_alloc_coherent#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))禁用cahceable 和 bufferable2.dma_alloc_writecombine#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)禁用cahceable
cma vs umpcma: 管理連續記憶體,可以預留好,可以用到時分配。4412BSP中為預留。ump:mali使用記憶體,使用時動態配分(alloc_page)
NEON多媒及加速指令集,增強ARM對多媒體處理能力,某些情境可以替代硬體處理單元。ARM? NEON? 通用 SIMD 引擎可有效處理當前和將來的多媒體格式,從而改善使用者體驗。NEON 技術可加速多媒體和訊號處理演算法(如視頻編碼/解碼、2D/3D 圖形、遊戲、音頻和語音處理、影像處理技術、電話和聲音合成),其效能至少為 ARMv5 效能的 3 倍,為 ARMv6 SIMD 效能的 2 倍。NEON 技術是通過乾淨方式構建的,並可無縫用於其本身的獨立管道和寄存器檔案。NEON 技術是 ARM Cortex?-A 系列處理器的 128 位 SIMD(單指令多資料)體繫結構擴充,旨在為消費性多媒體應用提供靈活強大的加速功能,從而明顯改善使用者體驗。 它具有 32 個寄存器,64 位元寬(是 16 個寄存器,128 位寬的雙倍視圖。)
request_mem_region && ioremap && phys_to_virt() Linux在標頭檔include/linux/ioport.h中定義了三個對I/O記憶體資源進行操作的宏:(1)request_mem_region()宏,請求分配指定的I/O記憶體資源。(2)check_mem_region()宏,檢查指定的I/O記憶體資源是否已被佔用。(3)release_mem_region()宏,釋放指定的I/O記憶體資源。 這三個宏的定義如下: #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) #define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) #define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) 其中,參數start是I/O記憶體資源的起始物理地址(是CPU在RAM物理地址空間中的物理地址),參數n指定I/O記憶體資源的大小。在請求IO記憶體資源成功後,開始用ioremap進行映射操作。 void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 將一個IO地址空間映射到核心的虛擬位址空間上去,便於訪問。入口:phys_addr是要映射的起始的IO地址;size是要映射的空間的大小;flag是要映射的IO空間的和許可權有關的標誌; 實現:對要映射的IO地址空間進行判斷,低PCI/ISA地址不需要重新對應,也不允許使用者將IO地址空間映射到正在使用的RAM中,最後申請一個 vm_area_struct結構,調用remap_area_pages填寫頁表,若填寫過程不成功則釋放申請的vm_area_struct空間;根據虛擬位址和欲映射的物理地址修改頁表,之後核心就可以用這個虛擬位址來訪問映射的物理地址了。對於直接映射的I/O地址ioremap不做任何事情(比如不帶MMU的Uclinux中就直接返回物理地址) 。有了ioremap(和iounmap),裝置就可以訪問任何I/O記憶體空間,不論它是否直接映射到虛擬位址空間。但是,這些地址永遠不能直接使用(像kmalloc返回的地址那樣用),而要用readb這種函數。同樣是從物理地址分配得到虛擬位址,還有以下這個函數:phys_to_virt()實際地址轉換成虛擬位址,兩者是有區別的。用ioremap 和 phys_to_virt 做物理地址於虛擬位址的轉換髮現:addr = (unsigned int volatile *)ioremap(0x56000088,12);printk(KERN_ALERT"%x\n",addr);addr = (unsigned int volatile *) phys_to_virt(0x56000088);printk(KERN_ALERT"%x\n",addr);兩個函數返回的addr值不一樣。原因在於:(1)在核心中phys_to_virt只是給地址減去一個固定的位移 :#ifndef __virt_to_phys#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)#endif注意:PHYS_OFFSET =0x50000000,在帶MMU的核心中,PAGE_OFFSET是0xc0000000;不帶MMU的核心中,與PHYS_OFFSET 同。(2)而ioremap()的原則就是核心會根據指定的物理地址建立映射頁表,物理地址和虛擬位址的關係就由這些頁表來搭建。:這個從ioremap的函數體可以看出來。