Ion記憶體的帶cahce與不帶cache問題分享
一次開發中,遇到一個問題:YUV影象(由本地磁碟檔案讀到ION記憶體中)縮放時,對於縮放模組的輸入源來說,使用帶cache的方式要比不帶cache的方式速度快數10倍。
為什麼會出現這個情況呢?
1.在解釋這個前,需要有一些基礎知識,可以回想一下volatile的用途。
它使用在什麼場景下呢?多個執行緒同時訪問一個全域性變數,例如執行緒1和執行緒2都對同一個記憶體地址的全域性變數進行讀/寫操作,這時就需要將這個變數宣告為volatile。
為什麼呢?為了加快cpu的訪問速度,會把一些變數值載入到暫存器中使用,當修改了該值後,其只更新在暫存器中,而不是在實際的mem中,雖然看似在對某記憶體地址上進行修改。而問題發生切換時,執行緒2中看到的相同地址下的值可能是執行緒1修改前的值。
因為cpu被這個執行緒使用時,cpu覺得“只有我一個人操作這個記憶體地址,因此我把這個值備份到更快速的地方(cache/register)來加快訪問速度,直到萬不得已我才把資料載入到mem中”,因此兩個執行緒看到的同一mem地址下的資料可能不相同。
2.藉此機會,再來引申,說明一下write-through和write-back的概念。
Write-through- Write is done synchronously both to the cache and to the backing store.
Write-back (or Write-behind) – Writing is done only to the cache. A modified cache block is written back to the store, just before it is replaced.
翻譯:
Write-through(直寫)——寫操作同時被更新到cache和後端儲存。
Write-back(回寫)——寫操作僅僅被更新到cache中。只有在這個cache將要被更新前,才將舊資料更新到後端儲存。
二者各有優缺點:直寫模式下,速度較慢,但資料安全。回寫模式下,速度快,但資料不安全(裝置斷電了!)。
機械硬碟就是一個很好的例子,例如往硬碟寫資料時,也是使用Write-back模式,先寫到硬碟的cache中,cpu就去幹其它事情了,而接下來時間磁碟可能偷偷將cahe中的資料重新整理到物理介質中。
從磁碟讀資料時,也是先將物理介質上一大塊資料載入到cache中,下次訪問附近的資料時,先在磁碟cache中看下是否能夠hit,如果命中了就不必再去物理磁軌上去讀資料。
3.OK,聯想打住,回到最初的問題。
為什麼ion記憶體分帶cache和不帶cache呢?很多模組(VideoCodec、cam、disp)都需要頻繁對mem資料進行更新。
例如h264碼流解碼後,需要將解碼器的output_buf的資料傳給(傳mem_addr)縮放模組,假如縮放模組進行soft scale down,cpu則去根據一定的演算法在mem中抽取畫素值。
假如不帶cache,那麼速度很慢,因為從phy mem上拿資料畢竟慢,但假如帶cache(資料也從phy_mem上重新整理到cache),則直接從cache中拿資料則很快。
同時,特別需要注意一點,這個cache是屬於cpu的,而其他外設不知道有這個cache,因而外設只是在實際phy_mem上進行資料更新;然而cpu對mem的訪問,表面上看似對phy_mem的訪問,但實際上可能是對其映象(cache)的訪問。
4.如何保證記憶體資料一致性呢?(帶cache的一個潛在後果)
當編解碼模組寫資料了後,cpu去讀,則需要呼叫特定的介面,強制從mem中讀資料,而不是從cache中讀資料。
當cpu寫資料(到cache)了後,編解碼模組需要呼叫特定的介面,將cache中的資料重新整理到mem中,編解碼模組再從mem中讀數