描述了在實時嵌入式系統(tǒng)開發(fā)中遇到的與CACHE有關(guān)的問題?對引起這些問題的原因——CACHE和RAM的不一致性進(jìn)行了討論?最后,提出了解決問題的方法?
隨著社會的發(fā)展?人們生活水平的提高,人們對嵌入式計算機(jī)應(yīng)用的要求也越來越高?因此,對嵌入式系統(tǒng)的性能要求也越來越高?明顯體現(xiàn)在嵌入式系統(tǒng)的CPU速度的不斷提高上?但問題也隨之而來,嵌入式CPU的主頻不斷地提高,一方面加強(qiáng)了CPU的處理能力,另一方面,在速度上造成了與慢速的系統(tǒng)存儲器極不相配的情況,從而影響了整個系統(tǒng)的性能?
為了解決這個問題,引入了CACHE技術(shù)?CACHE是一種高速緩沖存儲器,是為了解決CPU和主存之間速度不匹配而采用的一項重要技術(shù)?通過在主存和高速CPU之間設(shè)置一個小容量的高速存儲器,在其中存放CPU常用的指令和數(shù)據(jù),CPU對存儲器的訪問主要體現(xiàn)在對SRAM的存取,CPU可以不必加等待狀態(tài)而保持高速操作?
采用CACHE技術(shù),解決了CPU與主存之間速度不匹配的問題;但它又帶來了一些其它問題,如本文將提到的一致性問題?
1 問題的發(fā)現(xiàn)與原因
在進(jìn)行某嵌入式系統(tǒng)項目的開發(fā)過程中,有一個環(huán)節(jié)需要使用DMA方式進(jìn)行數(shù)據(jù)傳輸?當(dāng)程序運行后,發(fā)現(xiàn)傳到目的地的數(shù)據(jù)塊中經(jīng)常會有一些錯誤的字節(jié)?如:數(shù)據(jù)本應(yīng)為00 01 02 03 04 05 06 07 08 09 0A 0B 。..(16進(jìn)制),結(jié)果卻是00 01 02 03 00 00 00 00 08 09 0A 0B 。..?在某些環(huán)節(jié)也出現(xiàn)了類似的問題?例如,通過HDLC通道向外發(fā)送數(shù)據(jù),發(fā)送的總是緩沖區(qū)初始化時的內(nèi)容,實際要發(fā)送的數(shù)據(jù)總是發(fā)不出去,但使用調(diào)試工具看內(nèi)存中的數(shù)據(jù),卻是正確的?
經(jīng)過一段時間的調(diào)試,發(fā)現(xiàn)出現(xiàn)這種現(xiàn)象的環(huán)節(jié)都使用了DMA傳輸數(shù)據(jù)?在通過HDLC通道發(fā)送數(shù)據(jù)的例子中,HDLC通道內(nèi)部也是用DMA方式從內(nèi)存直接讀數(shù)據(jù)并向外發(fā)送?經(jīng)過分析,認(rèn)為問題的原因是出在CACHE上,是由于CACHE數(shù)據(jù)與內(nèi)存數(shù)據(jù)的不一致性造成的?
所謂CACHE數(shù)據(jù)與內(nèi)存數(shù)據(jù)的不一致性,是指:在采用CACHE的系統(tǒng)中,同樣一個數(shù)據(jù)可能既存在于CACHE中,也存在于主存中,數(shù)據(jù)一樣則具有一致性,數(shù)據(jù)若不一樣就叫做不一致性?具體表現(xiàn)在兩個方面:
(1)更新時可能CACHE中的數(shù)據(jù)更新,而主存未更新,則造成數(shù)據(jù)丟失;
(2)在有DMA控制器的系統(tǒng)和多處理器系統(tǒng)中,有多個部件可以訪問主存?這時,可能其中有些部件是直接訪問主存,也可能每個DMA部件和處理器配置一個CACHE?這樣,主存的一個區(qū)塊可能對應(yīng)于多個CACHE中的一個區(qū)塊?于是會產(chǎn)生主存中的數(shù)據(jù)被某個總線部件更新過,而某個CACHE中的內(nèi)容未更新,造成數(shù)據(jù)過時?
2 問題的分析
要解釋這個問題,首先要了解CACHE的工作模式?CACHE的基本工作模式有兩種:write-through模式和 copyback模式?在write-through模式下,所有的寫操作都寫入CACHE和RAM,保證了CACHE和RAM的一致?然而,每次對RAM都有寫操作會使處理器的處理能力降低,并且占用總線帶寬?在copyback模式下,寫操作只寫入CACHE,不寫入RAM,從而提高了處理器性能和總線帶寬?copyback模式下,CACHE中的內(nèi)容只有在需要的時候才寫到RAM中?當(dāng)CACHE中無可用空間時,一般使用最近最少使用算法(LRU)來決定哪一個CACHE項被替換?copyback模式提供了很高的系統(tǒng)性能,但是需要更多的一致性作保證?為了便于理解,給出一個使用了CACHE的系統(tǒng)的邏輯框圖,如圖1所示?
該系統(tǒng)中兩個地方會發(fā)生CACHE的不一致性:
(1)數(shù)據(jù)CACHE / RAM
數(shù)據(jù)CACHE與RAM之間的問題源于處理器和其他總線控制器對RAM的異步讀寫訪問?DMA設(shè)備和其他總線控制器對RAM的訪問是引起CACHE一致性問題的主要原因,這個問題可以通過在程序中加入一些代碼來解決?
(2)共享CACHE LINE
當(dāng)一個CACHE LINE被兩個以上的線程共享時,也會產(chǎn)生一致性問題?當(dāng)某個線程使一個CACHE LINE無效時,這個CACHE LINE中的一些項可能屬于另外一個線程?這個問題也可以通過一定的方法來避免,只要在分配內(nèi)存時大小是CACHE LINE大小的整數(shù)倍即可?
在哈佛體系結(jié)構(gòu)?copyback模式和無軟件干預(yù)的前提下,最佳的保持一致性的方法就是使用具有總線監(jiān)聽能力的硬件?將CACHE?RAM?DMA設(shè)備和其它所有的總線主控設(shè)備都連到一個物理總線上,以使CACHE可以對該總線上的總線交互過程進(jìn)行監(jiān)聽,CACHE將對總線上的地址周期和控制(讀/寫)比特監(jiān)聽,數(shù)據(jù)周期則被延遲到需要時才進(jìn)行?當(dāng)CACHE中的一項被一個異步操作修改時,該CACHE項就會被標(biāo)為無效?如果處理器對一個已經(jīng)被標(biāo)為無效的CACHE項進(jìn)行訪問時,CACHE就會從RAM中重新載入有效數(shù)據(jù)?在copyback模式下,處理器對CACHE進(jìn)行寫操作時,RAM相應(yīng)地址中的內(nèi)容就變成過時?如果另外一個設(shè)備想訪問RAM中的這部分內(nèi)容,CACHE就會搶占該訪問周期,將有效的數(shù)據(jù)寫入RAM?然后被搶占的訪問周期重新開始并將讀到RAM中的有效數(shù)據(jù)?但是,目前提供監(jiān)聽能力的板子并不多?
3 解決的方法
根據(jù)上面的分析和討論,可見問題正是由數(shù)據(jù)CACHE / RAM的不一致性引起的?雖然關(guān)掉CACHE就可以解決一致性的問題,并且能夠減小程序開發(fā)的復(fù)雜度?但是一個高性能的系統(tǒng)是需要CACHE的,關(guān)掉CACHE會大大降低系統(tǒng)的性能?因此,本文僅討論在程序中加入代碼來克服一致性問題的方法?
可以采用以下幾種加入代碼的方法來解決一致性的問題?本文使用WIND RIVER公司的嵌入式實時多任務(wù)操作系統(tǒng)VxWORKS,下面的函數(shù)都是VxWORKS提供的 :
(1)對于時間上不是那么關(guān)鍵的程序段,可以先用下面的代碼維護(hù)數(shù)據(jù)CACHE的一致性?
cacheInvalidate DATA_CACHE address bytes
/ 輸入緩沖區(qū)/
。..
cacheFlush DATA_CACHE address bytes
/輸出緩沖區(qū)/
(2)對于時間上比較關(guān)鍵的程序段采用如下原則:在每次使用輸出緩沖區(qū)前將其更新;在每次使用輸入緩沖區(qū)前使其無效?
將緩沖區(qū)標(biāo)示為“non-cacheable”可以防止一致性問題,這需要MMU支持?在分配緩沖區(qū)時,將其標(biāo)示為“non-cacheable”即可?然而,動態(tài)緩沖區(qū)在釋放時要標(biāo)為“cacheable”,否則內(nèi)存總會產(chǎn)生大量的緩沖區(qū)碎片?
下面給出一個高性能的驅(qū)動程序例子,它把更新/無效的概念進(jìn)行了擴(kuò)展?不是對整個CACHE系統(tǒng),而是對每一個緩沖區(qū)都這樣做?即通過分配對CACHE安全的緩沖區(qū),在一個緩沖區(qū)的基礎(chǔ)上操作,從而防止了不需要的更新/無效操作?在這個例子中使用了CACHE庫中的函數(shù)cacheDMAMalloc? ,宏CACHE_DMA_INVALIDATE和CACHE_DMA_FLUSH實現(xiàn)一致性?在第4行調(diào)用函數(shù)cacheDMAMalloc 后,如果指針返回為非空,則說明分配到了一塊對于一致性問題來說是安全的緩沖區(qū)?
第7行驅(qū)動程序在緩沖區(qū)中寫入要傳給外部設(shè)備的數(shù)據(jù),在第9行準(zhǔn)備傳給外設(shè)之前,驅(qū)動程序必須更新數(shù)據(jù)CACHE以保證要傳的數(shù)據(jù)是在內(nèi)存中,而不是在CACHE中?
當(dāng)驅(qū)動程序準(zhǔn)備讀外設(shè)傳給內(nèi)存的數(shù)據(jù),在第13行驅(qū)動程序處理這些數(shù)據(jù)之前,必須使數(shù)據(jù)CACHE中對應(yīng)于輸入緩沖區(qū)的那部分無效以消除這些包含過時內(nèi)容的條目?之后,驅(qū)動程序才能安全地處理從內(nèi)存中取來的輸入數(shù)據(jù)?
1: STATUS drvExample pBuf
2: void pBuf / 緩沖區(qū)指針 /
3: { /*
4: pBuf = cacheDMAMalloc BUF_SIZE
5: if pBuf == NULL
6: return ERROR /內(nèi)存分配失敗/
7: /其它初始化代碼和向發(fā)送緩沖區(qū)填數(shù)據(jù)/
8: CACHE_DMA_FLUSH pBuf BUF_SIZE
9: drvWrite pBuf /向外設(shè)發(fā)送數(shù)據(jù)/
10: …… / 其它代碼 /
11: drvWait /等待外設(shè)來的數(shù)據(jù)/
12: CACHE_DMA_INVALIDATE pBuf BUF_SIZE
13: / 處理外設(shè)來的數(shù)據(jù) /
14: cacheDMAFree pBuf /釋放內(nèi)存 /
15: return OK
16:}
責(zé)任編輯:gt
-
處理器
+關(guān)注
關(guān)注
68文章
19293瀏覽量
229977 -
嵌入式
+關(guān)注
關(guān)注
5083文章
19131瀏覽量
305551 -
存儲器
+關(guān)注
關(guān)注
38文章
7493瀏覽量
163879
發(fā)布評論請先 登錄
相關(guān)推薦
評論