<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 嵌入式編程需注意的Cache機(jī)制及其原理

          嵌入式編程需注意的Cache機(jī)制及其原理

          作者: 時(shí)間:2013-03-05 來(lái)源:網(wǎng)絡(luò) 收藏
            Cache的原理

            Cache即高速緩存,它的出現(xiàn)基于兩種因素:一、CPU的速度和性能提高很快,而主存速度較低且價(jià)格高;二、程序執(zhí)行的局部性特點(diǎn)。將速度較快而容量有限的SRAM構(gòu)成Cache,可以盡可能發(fā)揮CPU的高速度。CPU與外設(shè)交換數(shù)據(jù)時(shí)經(jīng)常用到buffer(緩沖),這與緩存極其相似,只不過(guò)Cache是為了提高CPU和內(nèi)存之間的數(shù)據(jù)交換速度而設(shè)計(jì),而buffer是為了提高內(nèi)存和硬盤(pán)(或其他I/O設(shè)備)之間的數(shù)據(jù)交換速度而設(shè)計(jì)的。

            Baidu快照(cache.baidu.com)就是一個(gè)緩存的例子,其作用與計(jì)算機(jī)CPU緩存有類(lèi)似之處。 Cache的原理如圖1所示。


            在讀取內(nèi)存數(shù)據(jù)的同時(shí)CPU將數(shù)據(jù)保存到Cache數(shù)據(jù)區(qū),同時(shí)更新Cache映射表(保存地址信息,表示該地址的數(shù)據(jù)是否已在Cache數(shù)據(jù)區(qū),即是否命中)。這樣,CPU再次讀取該地址數(shù)據(jù)時(shí),就可以直接從Cache提取。讀Cache的時(shí)間遠(yuǎn)小于直接讀內(nèi)存,可提高CPU讀取數(shù)據(jù)的效率。

            Cache數(shù)據(jù)區(qū)有成塊讀取的特性(Cache映射表保存的地址是塊地址,節(jié)省空間,也符合程序執(zhí)行的局部性特點(diǎn))。Cache數(shù)據(jù)區(qū)遠(yuǎn)遠(yuǎn)小于內(nèi)存空間,就需要相應(yīng)的替代算法。比如最近最少使用算法,可將新數(shù)據(jù)替代使用頻率低的數(shù)據(jù),同時(shí)更新映射表信息。可以推想,Cache空間越大,命中率越高。

            寫(xiě)內(nèi)存需要直接更新內(nèi)存。如果映射表存在該地址信息,還需要同時(shí)更新Cache數(shù)據(jù)區(qū)。這種Cache訪問(wèn)方式就稱(chēng)作“直寫(xiě)”,Samsung公司的ARM7微處理器S3CA510B就是這種方式。以下所討論的Cache問(wèn)題除非特殊說(shuō)明,否則都是“直寫(xiě)”方式。

            2 時(shí)需注意的問(wèn)題

            2.1 訪問(wèn)外設(shè)使用Cache的問(wèn)題

            在訪問(wèn)內(nèi)存時(shí)使用Cache是不會(huì)出現(xiàn)問(wèn)題的,但如果訪問(wèn)數(shù)據(jù)易變外設(shè)(數(shù)據(jù)不依賴(lài)于CPU寫(xiě)操作而改變)時(shí)使用Cache就可能出現(xiàn)問(wèn)題。問(wèn)題在于外設(shè)數(shù)據(jù)的改變不僅僅依靠CPU寫(xiě)操作,CPU第一次讀取外設(shè)數(shù)據(jù)時(shí)將外設(shè)的數(shù)據(jù)和地址信息保存到Cache,第二次讀取外設(shè)數(shù)據(jù)時(shí)就可能有問(wèn)題出現(xiàn)。這是因?yàn)閿?shù)據(jù)直接從Cache提取,而外設(shè)的數(shù)據(jù)可能有改變。

            因此,在訪問(wèn)易變外設(shè)時(shí)要禁止使能Cache,直接讀取外設(shè)數(shù)據(jù)到CPU,而不經(jīng)過(guò)Cache的任何環(huán)節(jié),即保證不改變Cache映射表和Cache數(shù)據(jù)區(qū)內(nèi)容。

            的SYSCFG SFR(特殊功能寄存器)有用來(lái)控制Cache使能或不使能的,通過(guò)對(duì)該SFR的設(shè)置可暫時(shí)禁止Cache或重新恢復(fù)Cache功能。這樣就可以在讀取外設(shè)前禁止Cache,讀取結(jié)束后重新使能Cache,保證了外設(shè)數(shù)據(jù)讀取的正確性。寫(xiě)數(shù)據(jù)到外設(shè)時(shí)采用“直寫(xiě)”方式,更沒(méi)有問(wèn)題。

            2.2 開(kāi)關(guān)Cache引發(fā)的新問(wèn)題

            在Cache開(kāi)關(guān)期間,如果有另一個(gè)進(jìn)程/任務(wù)訪問(wèn)內(nèi)存,在此期間寫(xiě)內(nèi)存并且該內(nèi)存在Cache中已有映射(注意,它也是被禁止Cache的,所以它不會(huì)同時(shí)更新Cache數(shù)據(jù)區(qū)的內(nèi)容),那么在Cache重新使能之后Cache數(shù)據(jù)區(qū)的信息已經(jīng)過(guò)時(shí)了,而Cache映射表還是Cache禁止之前的狀態(tài),如果CPU此時(shí)讀數(shù)據(jù)就會(huì)得到過(guò)時(shí)的數(shù)據(jù)。這樣看來(lái),引發(fā)的問(wèn)題范圍更廣了,連內(nèi)存的數(shù)據(jù)讀寫(xiě)正確性都無(wú)法保證。與內(nèi)存泄漏的影響來(lái)比較,內(nèi)存泄漏如果是一顆定時(shí)炸彈,那么Cache問(wèn)題就可以說(shuō)是隨時(shí)隨地都可能踩上的雷區(qū),因?yàn)槌绦蛞坏╅_(kāi)始就可能引發(fā)爆炸。



            如圖2所示,Cache使能時(shí)Cache映射表和Cache數(shù)據(jù)區(qū)保存了內(nèi)存的數(shù)據(jù)信息,這是CPU訪問(wèn)內(nèi)存時(shí)通過(guò)圖中實(shí)線箭頭通路實(shí)現(xiàn)的。內(nèi)存的信息可以與Cache的信息保持一致。

            Cache禁止時(shí)的情況有所變化。由圖2中虛線箭頭通路直接進(jìn)行內(nèi)存訪問(wèn),且地址0x00處的數(shù)據(jù)由55變?yōu)锳A,但Cache區(qū)的信息仍為之前的狀態(tài)。很明顯,Cache的數(shù)據(jù)是應(yīng)該廢棄的,但是Cache映射表仍保存0x00的地址信息。Cache重新使能后,CPU再次讀取0x00地址的數(shù)據(jù),由于Cache仍是命中,直接從Cache數(shù)據(jù)區(qū)中提取數(shù)據(jù),這樣讀出來(lái)的數(shù)據(jù)就是0x55了。

            由數(shù)據(jù)手冊(cè)第4節(jié)的第21頁(yè)可知:通過(guò)對(duì)SYSCFG寄存器的CE位置1或清0可使能/關(guān)閉Cache,但是Cache沒(méi)有內(nèi)容自動(dòng)刷新功能,在重新使能Cache時(shí)需考慮Cache數(shù)據(jù)的正確性。


          上一頁(yè) 1 2 下一頁(yè)

          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();