Ion內存的帶cahce與不帶cache問題分享

  • 2019 年 10 月 3 日
  • 筆記

一次開發中,遇到一個問題: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中讀數據。