CPU體系結構-Cache
cache的相關術語
- cachelinecacheline是cache的最小操作力度,當前的cpu體系中,多為64bytes的data,但cacheline本身還包括了valid,dirty,NS等bit位.
- setset中包括多個cacheline,N-Way的cache,則包含了N個cacheline
- way如上,一個set中cacheline的個數
- blockblock這個概念現在不常提了,一般可以默認block和cacheline是一件事情,如果非要說不同,可以認為block是cacheline中除了valid,dirty, ns位意外的位元組,具體的data數據。
cache的映射與定址
- 映射方式 cache的組成方式,有直接映射,組相連映射,全相連映射。 分別表示一個地址(物理地址)。對應cache中存放位置的映射方式。
一張圖看懂cache映射方式
- cache定址
cache的策略與地址屬性
- Write allocation (WA) 如果這個寫操作,發生了了cachemiss,那表示這寫之前,會有一個cacheline的fill過程,即使寫一個byte,也會把這一個byte所在的64bytes(cacheline-size)全部load到cacheline中。
- Read allocation (RA) 同WA,當發生了cachemiss時,同理。
- Write-back (WB) 寫操作只操作cache,並把對應的cacheline標記為dirty,當發生了cache替換策略時,或者強制執行了cacheline的操作。才會update到memory(DDR)中。
- Write-through (WT) 同時寫到了cache和memory中,但不會標記cacline為dirty,因為本來也不是dirty,cache和memory中的數據是一樣的。
cache指令與PoU PoC
- PoU(Point of unification) cache的統一性,一般是從cpu的維度,即cpu間看到的cache一致性。
- PoC (Point of coherency) cache的一致性,這個是大一統,即從SoC的較多,多個master之間看到的一致性,一般就是到memory層了,比如cpu和dma看到的一致性。
- cache指令
DCCISWClean and invalidate by Set/Way CIVACClean and Invalidate by Virtual Address to Point of Coherency CSWClean by Set/Way CVACClean by Virtual Address to Point of Coherency CVAUClean by Virtual Address to Point of Unification ISWInvalidate by Set/Way IVACInvalidate by Virtual Address, to Point of Coherency ZVACache zero by Virtual AddressICIALLUISInvalidate all, to Point of Unification, Inner Sharable IALLUInvalidate all, to Point of Unification, Inner Shareable IVAUInvalidate by Virtual Address to Point of Unification
由上可見,只有dache有PoC/PoU的概念,ICACHE不涉及,不需要與其他master保持指令一致性。
D-cache的invalid和clean一般有DC IVAC IVAU從PoC和PoU兩個角度。
當然還包括了ISW/CISW通過set way的方式。 但是需要注意的是這樣的set/way的操作方式,沒有從PoC的角度,所以一般涉及到同master的一致性時,需要每個cpu都調用。內存屬性與指令序列
- Normal Memory
Normal-memory的性能最高,這沒用明確的數據依賴的前提下,可以亂序,重組。
可以產生分支預測,cache-line-fill等操作。
- Device Memory
Device屬性,一般用於產生side-effect效應的地址。比如讀取timer(寄存器),寫contoller觸發一個中斷等場景
- Device-nGnRnE與ARMV7的strong-order類似
- Device-nGnRE
- Device-nGRE
- Device-GRE
- Gathering or non Gathering (G or nG)
是否可以合併,用於告訴處理器是否可以將多個access合併成一個bus-transaction. 如果是nG的話,每次core交給匯流排的數據長度根code中的一致,如果是G(Gathering)的話,例如可以將多個byte單位元組的操作合併成一個word操作。另外一個是repeat,當某條load/store指令在pipeline的access memory階段,發生cache miss(對於non-cacheable的memory就直接跳過,不過對於device memory一般都是non-cacheable的)後,需要將access memory請求發到匯流排上(例如AXI匯流排),通過AXI匯流排訪問device memory,這個通過匯流排訪問memory的過程被稱為一次transaction. 為了優化性能考慮,在core內,會引入一個Buffer, 當發生一個access memory請求後,會將這個請求信息丟到Buffer中,若某條指令和上一條指令共享同一個cache line或者是訪問同一個地址,那麼,該條指令便不會再向匯流排發送transaction了,它share上一條指令 讀到buffer中的結果。這個share的過程稱為gathering. 讀到buffer中的數據,如果是cacheable的,會在某個時間內騰到cache中。
- Re-ordering (R or nR)
eordering也是針對device memory的transaction, that is, 某個device memory的連續access的transaction或者device memory之間的連續access的transaction. 對某個device memory的一次transaction 必須等到上一次device memory的transaction結束後(上一次load或者 write的ack發生後)才可以進行,這叫non-reordering. 若這些transaction可以亂序,不需要等待上一次access的ack就可以進行transaction,這種方式叫reordering
- Early Write Acknowledgement (E or nE)
當對某個Device memory進行write時,需要ACK,下一個對device memory進行access的transaction才能進行。為了性能優化的考慮,device會提供一個類似與寄存器的程序員不可見的buffer,這樣當CPU通過匯流排向device memory寫數據的時候,直接寫到buffer里就可以了。這樣buffer就可以向cpu返回一個ACK,表示寫successfully.至於何時buffer將數據真正騰到device memory就看device內部的協議了,一般是DMC(DDR CONTROLLER)這邊的操作。
- Barriers 屏障
ARM體系結構提供了屏障的指令,主要用來保證執行的順序和完成的順序。
- ISB (Instruction Synchronization Barrier)
指令同步屏障,一般保證指令的fetch順序(官方說的是fetch,我理解就是執行順序),如檢查MMU的配置,寫系統寄存器。
- DMB(Data Memory Barrier)
阻止數據的re-order,但是指令的prefetch不阻止
LDR x0, [x1] // Must be seen by the memory system before the STR below.
DMB ISHLD
ADD x2, #1 // May be executed before or after the memory system sees LDR.STR x3, [x4] // Must be seen by the memory system after the LDR above.上面 LOAD X1地址內容到X0下面 STORE X3到X4的地址保證了數據的存儲順序
DC CSW, x5 // Data clean by Set/way
LDR x0,
[x1] // Effect of data cache clean might not be seen by this instructionDMB ISHLDR x2, [x3] // Effect of data cache clean will be seen by this instruction刷cacheDMB 保證LDR X2,[X3]會這刷cache完成
- DSB(Data Synchronization Barrier)
DSB可以理解為更嚴格的DMB,除了存儲屏障意外,還阻止了指令的prefetch
尤其這core同步的時候比較有用,比如SMP裡邊,通知core啟動之前,需要刷新cache,刷新tlb等操作
然後SEV(send event),順便說下,WFE和WFI均進入低功耗模式,均可以被irq喚醒,WFE還可以被任何core的SEV喚醒,類似spinlock的實現。Core1訪問資源,acquire lock,獲得資源,Core2訪問資源,此時資源不空閑,執行WFE指令,讓core進入low-power state,Core1釋放資源,release lock,釋放資源,同時執行SEV指令,喚醒Core2。這裡SEV可以同時喚醒多個core,即所有core有相同的幾率得到spinlock。Core2得到獲得資源。以前沒有獲得資源會loop busy,現在有了WFE可以low-power standby節省功耗。
DC ISW, x5 // operation must have completed before DSB can complete STR x0, [x1] // Access must have completed before DSB can complete DSB ISH
ADD x2, x2, #3 // Cannot be executed until DSB completes
- Volatile
volatile是防止編譯器優化指令,與地址本身的cache和device屬性無關
如下面代碼
void non_vo_test(void)
{
int *test = 3; int data; data = *test;}void vo_test(void){ volatile int *test = 3; int data; data = *test;}
0000000000000184 <non_vo_test>:
184: d65f03c0 ret
0000000000000188 <vo_test>:
188: d2800060 mov x0, #0x3 // #3
18c: b9400000 ldr w0, [x0]190: d65f03c0 ret
告訴編譯器永遠發出對應地址的指令操作,不是優化掉。
推薦閱讀: