思考
- L1 System memory 和 L1 Cache 是什么關(guān)系?
- L1 指令 cache 禁用時(shí),指令 cache 就真的不會(huì)緩存了嗎?此時(shí)還會(huì)出現(xiàn)緩存不一致的情況嗎?
- L1 data cache 禁用時(shí),L1 data cache 就真的不會(huì)緩存了嗎?此時(shí)還會(huì)出現(xiàn)緩存不一致的情況嗎?
- 在下電的時(shí)候,cache 有什么自動(dòng)的行為?
- 有沒有 invalidate the entire data cache 的操作?那操作系統(tǒng)中的 invalidate_all_cache 是如何實(shí)現(xiàn)的?
- 什么是 Branch Target Buffer (BTB)?
- 什么是 Write streaming mode?軟件怎樣可以影響到 Write streaming mode 的行為?
- 有關(guān) cache 的 refill,如果 L1 MISS,那么 L1 會(huì)發(fā)生 refill 嗎
- Armv9 中的原子指令,和 cache 有啥關(guān)系?
- Exclusive 機(jī)制和 cache 有啥關(guān)系?
- 數(shù)據(jù)預(yù)取的作用是什么?數(shù)據(jù)預(yù)取有哪些指令?
- 執(zhí)行 memset() 函數(shù)清空一大塊內(nèi)存的時(shí)候,這些地址數(shù)據(jù)都會(huì)進(jìn) cache 嗎?
本節(jié)課我們將講述 Armv9 Cortex-A720 的 L1 System memory.
7 L1 instruction memory system
Cortex-A720 的 L1 指令內(nèi)存系統(tǒng)用于提取指令并預(yù)測分支。它包括 L1 指令緩存、L1 指令 Translation Lookaside Buffer(TLB)以及分支預(yù)測單元。L1 指令內(nèi)存系統(tǒng)向解碼器提供指令流。為了提高整體性能并降低功耗,L1 指令內(nèi)存系統(tǒng)使用動(dòng)態(tài)分支預(yù)測和指令緩存。
下圖顯示了 L1 指令內(nèi)存系統(tǒng)的特性。
L1 指令 TLB 也位于 L1 instruction memory system 中,它是內(nèi)存管理單元(MMU)的一部分。
7.1 L1 instruction cache behavior
在 reset 時(shí),除非 core 電源模式初始化為 “Debug Recovery”,否則 L1 指令緩存將自動(dòng)失效。在 Debug Recovery 模式下,L1 指令緩存不起作用。
L1 instruction cache 的禁用
禁用 L1 instruction cache 對(duì) L1 指令緩存的操作沒有影響。即使在禁用狀態(tài)下,指令仍可以緩存在 L1 指令緩存中并從中提取。軟件必須考慮 Non-cacheable accesses 以確保正確的行為。
如果禁用了 L1 instruction cache,那么由指令提取引起的所有內(nèi)存訪問都將使用 Non-cacheable accesses。這意味著指令提取可能與同一核心或其他核心中的緩存不一致。軟件必須考慮這一點(diǎn),執(zhí)行適當(dāng)?shù)木彺婢S護(hù)操作。
L1 instruction 維護(hù)
緩存維護(hù)操作可以在任何時(shí)候發(fā)生,不管 L1 的狀態(tài)是禁用還是啟用。
7.2 L1 指令緩存的推測性內(nèi)存訪問
指令提取是推測性的,流水線中可能存在多個(gè)未完成的分支。
代碼流中的分支指令或異??梢詫?dǎo)致流水線刷新,丟棄當(dāng)前已提取的指令。
在指令提取時(shí),具有 device memory 被視為 non-cacheable normal memory。為了防止指令提取,設(shè)備內(nèi)存頁面必須標(biāo)記為翻譯表描述符屬性位 "Xecute Never"(XN)。設(shè)備和代碼地址空間必須在物理內(nèi)存映射中分離。這種分離防止了在禁用地址轉(zhuǎn)換時(shí)對(duì)讀取敏感設(shè)備的推測性提取。
如果啟用了 L1 指令緩存并且指令提取在 L1 指令緩存中未命中,那么它們?nèi)匀豢梢栽?L1 數(shù)據(jù)緩存中查找。
然而,無論數(shù)據(jù)緩存是否啟用,查找都不會(huì)導(dǎo)致 L1 數(shù)據(jù)緩存重新填充 (refill)。該行僅 refill allocated 在 L2 緩存中,前提是 L1 指令緩存已啟用。
7.3 程序流預(yù)測
Cortex-A720 核包含程序流預(yù)測硬件,也稱為分支預(yù)測。分支預(yù)測提高了整體性能并增強(qiáng)了功耗效率。
當(dāng)內(nèi)存管理單元(MMU)啟用當(dāng)前異常級(jí)別時(shí),程序流預(yù)測被啟用。如果禁用程序流預(yù)測,那么所有已執(zhí)行的分支都會(huì)產(chǎn)生與清除流水線相關(guān)的動(dòng)作。如果啟用程序流預(yù)測,則它會(huì)預(yù)測是否要執(zhí)行條件或無條件分支,如下所示:
- 對(duì)于條件分支,它預(yù)測是否要執(zhí)行分支以及分支轉(zhuǎn)到的地址,即分支目標(biāo)地址。
- 對(duì)于無條件分支,它僅預(yù)測分支目標(biāo)地址。
程序流預(yù)測硬件包含以下功能:
- 存儲(chǔ)以前已執(zhí)行分支的分支目標(biāo)地址的分支目標(biāo)緩沖器 Branch Target Buffer (BTB)
- 使用以前的分支歷史的分支預(yù)測(BP)預(yù)測器
- 返回堆棧,包括嵌套子例程返回地址
- 靜態(tài)分支預(yù)測器
- 間接分支預(yù)測器
預(yù)測和非預(yù)測指令
- 序流預(yù)測硬件預(yù)測所有分支指令,包括:
- 條件分支
- 無條件分支
- 返回指令
- 間接分支
以下指令不會(huì)被預(yù)測:
- 異常返回指令(包括 ERET,ERETAA,ERETAB)
- svc 指令
- hvc 指令
- smc 指令
返回棧
返回棧存儲(chǔ)了過程調(diào)用指令的返回地址。此地址應(yīng)與這些指令由 Link 寄存器(X30)寫入的值相等。
以下任何指令都會(huì)導(dǎo)致壓棧:
- BL
- BLR
- BLRAA
- BLRAAZ
- BLRAB
- BLRABZ
以下任何指令都會(huì)導(dǎo)致出棧:
- RET
- RETAA
- RETAB
8 L1 data memory system
Cortex-A720 的 L1 數(shù)據(jù)內(nèi)存系統(tǒng)執(zhí)行加載和存儲(chǔ)指令。它處理內(nèi)存一致性請(qǐng)求以及特定指令,如原子操作、緩存維護(hù)操作和內(nèi)存標(biāo)記指令。L1 數(shù)據(jù)內(nèi)存系統(tǒng)包括 L1 數(shù)據(jù)緩存和 L1 數(shù)據(jù) Translation Lookaside Buffer(TLB)。
下表顯示了 L1 數(shù)據(jù)內(nèi)存系統(tǒng)的特性。
L1 數(shù)據(jù) TLB 也位于 L1 數(shù)據(jù)內(nèi)存系統(tǒng)中,它是內(nèi)存管理單元(MMU)的一部分。
8.1 L1 數(shù)據(jù)緩存行為
除非將核心電源模式初始化為 Debug 恢復(fù)模式,否則 L1 數(shù)據(jù)緩存將在重置時(shí)自動(dòng)失效。在 Debug 恢復(fù)模式下,不能保證緩存是否正常運(yùn)行,因此不應(yīng)啟用。
沒有使整個(gè) data cache 失效的操作 (invalidate the entire data cache)。如果軟件需要這個(gè)功能,那么必須通過循環(huán)執(zhí)行的單獨(dú)失效操作(通過 set/way 指令)來構(gòu)建它。DC CISW 指令執(zhí)行目標(biāo) set/way 的清除和失效操作。
禁用 data cache 行為
如果禁用數(shù)據(jù)緩存行為,則:
- 由于加載指令而導(dǎo)致的 L2 或 L3 緩存不會(huì)分配新的行。
- 對(duì)可緩存內(nèi)存的所有加載和存儲(chǔ)指令都視為 Non-cacheable。
- 數(shù)據(jù)緩存維護(hù)操作繼續(xù)正常執(zhí)行。
L1 數(shù)據(jù)緩存和 L2 緩存不能獨(dú)立禁用。當(dāng)一個(gè)核心禁用 L1 數(shù)據(jù)緩存時(shí),由該核心發(fā)出的可緩存內(nèi)存訪問將不再在 L1 或 L2 緩存中緩存。在多個(gè) core 之間 cache 的維護(hù)操作,使用 Modified Exclusive Shared Invalid (MESI) 協(xié)議
緩存索引的確定方式意味著物理地址(PA)和組編號(hào)之間沒有直接關(guān)系。不能使用假設(shè) PA 和組編號(hào)之間存在關(guān)系的有針對(duì)性的操作。要刷新整個(gè)緩存,必須根據(jù)緩存的 CCSIDR_EL1 描述的組和方式數(shù)量執(zhí)行組和方式維護(hù)操作。
8.2 Write streaming mode
Cortex-A720 核心支持 Write streaming mode,有時(shí)也稱為讀分配模式,對(duì)于 L1 和 L2 緩存都支持。
在讀不命中或?qū)懖幻袝r(shí),會(huì)向 L1 或 L2 緩存分配緩存行。然而,寫入大塊數(shù)據(jù)可能會(huì)使緩存中充滿不必要的數(shù)據(jù)。這不僅會(huì)浪費(fèi)電力,也會(huì)降低性能,因?yàn)檎麄€(gè)線路會(huì)被后續(xù)寫入覆蓋(例如使用 memset() 或 memcpy())。在某些情況下,不需要在寫入時(shí)分配緩存行。例如,當(dāng)執(zhí)行 C 標(biāo)準(zhǔn)庫的 memset() 函數(shù)來將大塊內(nèi)存清零為已知值時(shí)。
為了防止不必要的緩存行分配,內(nèi)存系統(tǒng)會(huì)檢測 core 何時(shí)寫入了一系列完整的緩存行。如果在可配置數(shù)量的連續(xù)線路填充上檢測到這種情況,那么它會(huì)切換到寫入流模式。
在寫入流模式下,加載操作行為與正常情況相同,仍然可能引起線路填充。
寫入仍然在緩存中查找,但如果未命中,則會(huì)寫入 L2 或 L3 緩存,而不會(huì)啟動(dòng)線路填充 L1。
在內(nèi)存系統(tǒng)切換到寫入流模式之前,CHI 主控器或 AXI 主控器接口可能會(huì)觀察到超過指定數(shù)量的線路填充。
寫入流模式保持啟用,直到以下情況之一發(fā)生:
? 檢測到一個(gè)不是完整緩存行的可緩存寫入突發(fā)。
? 存在后續(xù)加載操作,其目標(biāo)與未完成的寫入流相同。
當(dāng) Cortex-A720 核心切換到寫入流模式后,內(nèi)存系統(tǒng)會(huì)繼續(xù)監(jiān)視總線流量。當(dāng)它觀察到一系列完整的緩存行寫入時(shí),會(huì)向 L2 或 L3 緩存發(fā)出信號(hào),以進(jìn)入寫入流模式。
寫入流閾值定義了在存儲(chǔ)操作停止引起緩存分配之前,連續(xù)寫入的緩存行數(shù)量。您可以通過寫入寄存器 IMP_CPUECTLR_EL1 來配置每個(gè)緩存(L1、L2 和 L3)的寫入流閾值。
8.3 L1 數(shù)據(jù)內(nèi)存系統(tǒng)中的原子指令實(shí)現(xiàn)
Cortex-A720 核心支持 Arm v8.1-A 架構(gòu)中添加的原子指令。對(duì)可緩存內(nèi)存的原子指令可以作為近原子操作或遠(yuǎn)原子操作執(zhí)行,默認(rèn)情況下,Cortex-A720 核心將這些指令作為近原子操作執(zhí)行。
換句說法,可以根據(jù)系統(tǒng)行為對(duì) IMP_CPUECTLR_EL1 進(jìn)行編程,以便某些原子指令嘗試作為原子操作執(zhí)行。
當(dāng)作為遠(yuǎn)原子操作執(zhí)行時(shí),原子操作傳遞給 interconnect 執(zhí)行操作。如果操作在集群內(nèi)的任何位置 hit,或者如果互連器不支持原子操作,則 L3 內(nèi)存系統(tǒng)執(zhí)行原子操作。如果該行不存在,則將其分配到 L3 緩存中。
Cortex-A720 核心支持對(duì) device 或 non-cacheable 的原子操作,但這也依賴于互連器是否支持原子操作。如果在互連器不支持原子操作的情況下執(zhí)行此類原子操作指令,則會(huì)導(dǎo)致 abort。
8.4 內(nèi)部獨(dú)占監(jiān)視器
Cortex-A720 核心包括一個(gè)內(nèi)部獨(dú)占監(jiān)視器,具有 2 狀態(tài)(open 狀態(tài)和 exclusive 狀態(tài))的狀態(tài)機(jī),用于管理 Load-Exclusive 和 Store-Exclusive 訪問以及 Clear-Exclusive(CLREX)指令。
您可以使用這些指令構(gòu)建信號(hào)量,確保不同進(jìn)程在核心上運(yùn)行時(shí)進(jìn)行同步,以及確保使用相同的一致內(nèi)存位置的不同核心之間進(jìn)行同步。Load-Exclusive 指令標(biāo)記了一小塊內(nèi)存以進(jìn)行獨(dú)占訪問。CTR_EL0 定義了標(biāo)記塊的大小為 16 個(gè)字,即一個(gè)緩存行。
Load-Exclusive 或 Store-Exclusive 指令是以 LDX、LDAX、STX 或 STLX 開頭的指令。
8.5 數(shù)據(jù)預(yù)取
數(shù)據(jù)預(yù)取可以通過在需要數(shù)據(jù)之前獲取數(shù)據(jù)來提高執(zhí)行性能。
預(yù)加載指令
對(duì)于不能有效處理數(shù)據(jù)預(yù)取器的情況,Cortex-A720 核心支持 AArch64 預(yù)取內(nèi)存指令 PRFM。
這些指令向內(nèi)存系統(tǒng)發(fā)出信號(hào),指定地址處的內(nèi)存訪問可能會(huì)很快發(fā)生。當(dāng)內(nèi)存訪問發(fā)生時(shí),內(nèi)存系統(tǒng)采取措施以減少內(nèi)存訪問的延遲。
PRFM 指令在緩存中執(zhí)行查找。如果未命中并且內(nèi)存訪問是對(duì)可緩存地址的,則開始線路填充。但是,PRFM 指令在開始線路填充時(shí)執(zhí)行結(jié)束,并且不會(huì)等到線路填充完成。
硬件數(shù)據(jù)預(yù)取器
加載 / 存儲(chǔ)單元包括硬件預(yù)取器引擎,負(fù)責(zé)生成針對(duì) L1、L2 和 L3 緩存的預(yù)取。具體來說,L1 內(nèi)存子系統(tǒng)中的預(yù)取引擎針對(duì) L1 和 L2 緩存。L2 內(nèi)存子系統(tǒng)中的預(yù)取引擎針對(duì) L2 和 L3 緩存。加載端預(yù)取器使用虛擬地址(VA)和程序計(jì)數(shù)器(PC)。存儲(chǔ)端預(yù)取器僅使用虛擬地址(VA)。CPUECTLR 寄存器允許對(duì)預(yù)取器行為的某些方面進(jìn)行控制。
數(shù)據(jù)緩存清零
在 Cortex-A720 核心中,Data Cache Zero by Virtual Address(DC ZVA)指令將對(duì)齊到 64 字節(jié)的內(nèi)存塊(64 字節(jié)對(duì)齊)設(shè)置為零。
-
緩沖器
+關(guān)注
關(guān)注
6文章
1921瀏覽量
45473 -
ARM芯片
+關(guān)注
關(guān)注
1文章
125瀏覽量
21466 -
MMU
+關(guān)注
關(guān)注
0文章
91瀏覽量
18283 -
Cortex-A7
+關(guān)注
關(guān)注
0文章
34瀏覽量
16493 -
cache技術(shù)
+關(guān)注
關(guān)注
0文章
41瀏覽量
1062
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論