漫畫:什么是 volatile 關(guān)鍵字?
956
2025-04-01
隨著計算機行業(yè)的飛速發(fā)展,CPU的速度和內(nèi)存的大小都發(fā)生了翻天覆地的變化,在處理器速度不斷增加的形勢下,處理器處理數(shù)據(jù)的能力也得到大大提升。數(shù)據(jù)是存儲在內(nèi)存中的,內(nèi)存吞吐率雖然得到很大的提升,但是相對于處理器來講,仍然非常慢。處理器要從內(nèi)存中直接讀取數(shù)據(jù)都要花大概幾百個時鐘周期,在這幾百個時鐘周期內(nèi),處理器除了等待什么也不能做。在這種環(huán)境下,才提出了Cache的概念。計算機中常見的存儲介質(zhì)如圖1所示,在梯形圖中從上到下容量依次遞增,速率依次遞減,每字節(jié)的成本依次遞減(圖中列出的外部存儲不是絕對滿足這兩條性質(zhì),由于受到生產(chǎn)工藝和時間的影響;寄存器訪問速度是最快的,編程有一個register關(guān)鍵字,對于重復次數(shù)很多的變量可以用register聲明,這個變量就被放到寄存器空間,寄存器空間很小,register不宜多用)。
圖1
CPU與內(nèi)存交互數(shù)據(jù)有兩種方式。圖2中(a)方式比較古老;(b)圖中引入了cache高速緩存,當CPU需要從內(nèi)存中獲取數(shù)據(jù)時,cache可以提前把CPU所需要指令和數(shù)據(jù)從內(nèi)存中預(yù)取到cache緩存中,CPU直接從cache中取指令和數(shù)據(jù)。沒有引入cache讀取依次內(nèi)存大約為150個時鐘周期,引入cache后,L3 cache命中讀取一次內(nèi)存需要40個時鐘周期。
圖2
Cache大多是SRAM(靜態(tài)RAM),而內(nèi)存大多是DRAM(動態(tài)隨即存儲)或者DDR(雙倍動態(tài)隨機存儲),Cache由三級組成,一級(L1)最快,但是容量最小;三級(LLC,Last Level Cache)最慢,但是容量最大。在多核CPU中每個核擁有獨立的L1和L2兩級cache,L1 Cache一般把指令和數(shù)據(jù)分布存放,數(shù)據(jù)Cache用來存儲數(shù)據(jù),而指令Cache用于存放指令,為了保證所有的核看到正確的內(nèi)存數(shù)據(jù),一個核在寫入L1 cache后,CPU會執(zhí)行Cache一致性算法(Cache一致性算法在本文不涉及)把對應(yīng)的cacheline(cache line是cache與內(nèi)存數(shù)據(jù)交換的最小單位,如圖3所示)同步到其他核,這個過程并不很快,是微秒級的,相比之下寫入L1 cache只需要若干納秒。當很多線程在頻繁修改某個字段時,這個字段所在的cache line被不停地同步到不同的核上,就像在核間彈來彈去,這個現(xiàn)象就叫做cache bouncing。三級 Cache 由所有的核所共有,由于共享的存在,有的處理器可能會極大地占用三級Cache,導致其他處理器只能占用極小的容量,從而導致Cache不命中,性能下降。英特爾公司推出了Intel? CAT技術(shù),通過軟件配置算法來控制每個核可以用到的Cache大小。
圖3
內(nèi)存的數(shù)據(jù)被加載到Cache后,在某個時刻其要被寫回內(nèi)存,寫內(nèi)存有如下5種策略:寫通(write-through)、寫回(write-back)、寫一次(write-once)、WC(write-combining)和UC(uncacheable)。
圖4
寫通(write-through):當cache寫命中時,處理器對Cache寫入的同時,將數(shù)據(jù)寫入到內(nèi)存中,內(nèi)存的數(shù)據(jù)和Cache中的數(shù)據(jù)都是同步的,這種方式比較簡單、可靠。但是處理每次對cache更新都需要對內(nèi)存寫操作,因此總線工作繁忙,內(nèi)存的帶寬被大大占用,因此運行速度會受到影響。假設(shè)一段程序在頻繁地修改一個局部變量,局部變量生存周期很短,而且其他進程/線程也用不到它,CPU依然會頻繁地在Cache和內(nèi)存之間交換數(shù)據(jù),造成不必要的帶寬損失。當cache寫未命中時,只有直接向主存寫入了,但此時是否將修改過的主存塊取到cache,寫直達法卻有兩種選擇。一是取來并且為它分配一個位置,稱為WTWA(Write--Through--with--Write--Allocate)。另一種是不取稱為WTNWA法(WriteThrough--with.NO-Write--Allocate)。前 一種法保持了cache/主存的一致性,但操作復雜,而后一種方法操作簡化,但命中率降低,內(nèi)存的修改塊只有在讀未命中對cache 進行替換時,才有可能射到cache 。寫通發(fā)保證了寫cache與寫主存同步進行,圖4中(a)圖為寫通法WTNWA法的流程圖。
寫回(write-back):當CPU對cache寫命中時,只修改cache的內(nèi)容不立即寫入主存,只當此行被換出時才寫回主存。這種策略使cache在CPU-主存之間,不僅在讀方而且在寫方向上都起到高速緩存作用。對一cache行的多次寫命中都在cache中快速完成修改,只是需被替換時才寫回速度較慢的主存,減少了訪問主的次數(shù)從而提高了效率。為支持這種策略,每個cache行必須配置一個修改位(就是圖三中狀態(tài)字節(jié)),以反映此行是否被CPU修改過。當某行被換出時,根據(jù)此行修改位為是為0。對于cache寫未命中,寫回法的處理是為包含欲寫字的主存塊在cache分配一行,將此塊整個拷貝到Cache后對其進行修改, 因為爾后對此塊的多讀/寫訪問的可能性很大。拷貝主存塊時雖已讀訪問到主存,但此時并不對主存塊修改。因為換出的cache很可能此期間要寫回主存,為避免此過程耗時長,寫未命中對將新塊讀入后,只在cache中進行寫修改。統(tǒng)一地將主存寫修改操作留待換出時進行,圖4中(b)圖為寫回策略的流程圖。
寫一次(write--once):寫一次是一種基于寫回又結(jié)合了寫通的寫策略,即寫命中和寫未命中的處理與寫回法基本相同,只是第一次寫命中時要同時寫入主存。這策略主要用于某些處理器的片內(nèi)cache,例如Pentium處理器的片內(nèi)數(shù)據(jù)cache就采用的是寫一次法。因為片內(nèi)cache寫命中時,寫操作就在CPU內(nèi)部高完成,若沒有 內(nèi)存地址及其它指示信號送出,就不便于系統(tǒng)中的其它cache監(jiān)聽(snoop)。采用寫一次法,在第一次片內(nèi)cache寫命中時,CPU要在線上啟動一個存儲寫周期。其它cache監(jiān)聽到此主存塊地址及寫信號后,即可把它們各自保存可能有的該塊拷貝及時作廢(無效處理)。爾后若有 對片cache此行的再次或多次寫命中,則按回寫法處理,無需再送出信號了。
WC(write-combining):write-combining策略是針對于具體設(shè)備內(nèi)存(如顯卡的RAM)的一種優(yōu)化處理策略。對于這些設(shè)備來說,數(shù)據(jù)從Cache到內(nèi)存轉(zhuǎn)移的開銷比直接訪問相應(yīng)的內(nèi)存的開銷還要高得多,所以應(yīng)該盡量避免過多的數(shù)據(jù)轉(zhuǎn)移。這種策略是一個Cache line里的數(shù)據(jù)一個字一個字地都被改寫完了之后,才將該 Cache line 寫回到內(nèi)存中。
UC(uncacheable):uncacheable 內(nèi)存是一部分特殊的內(nèi)存,比如PCI設(shè)備的I/O空間通過MMIO方式被映射成內(nèi)存來訪問。這種內(nèi)存是不能緩存在Cache中的,因為設(shè)備驅(qū)動在修改這種內(nèi)存時,總是期望這種改變能夠盡快通過總線寫回到設(shè)備內(nèi)部,從而驅(qū)動設(shè)備做出相應(yīng)的動作。如果放Cache中,硬件就無法收到指令。
軟件開發(fā)云
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。