參考文獻:《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》
1、內存類型
ARMv7-A 處理器中,將 Memory 定義為幾種類型(Memory Type):
- Strongly-ordered
- Normal
- Device
2、Normal memory
2.1 Non-shareable
Normal memory must also be designated either as Shareable or Non-Shareable. A region of Normal memory with the Non-Shareable attribute is one that is used only by this core. There is no requirement for the core to make accesses to this location coherent with other cores. If other cores do share this memory, any coherency issues must be handled in software. For example, this can be done by having individual cores perform cache maintenance and barrier operations.
——————《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》
對于 Normal memory 類型的內存區域:
-
必須指定為 Shareable 或 Non-Shareable
-
如果它被標記為 Non-Shareable:
- 硬件不會保證這塊內存在多個核心之間的數據一致性
- 默認認為只有當前核心在使用這塊內存
- 如果實際上多個核心訪問這塊內存,那就必須靠軟件來保證一致性,比如通過緩存管理(清除/失效)、內存屏障(DMB/DSB/ISB)、通信協議等手段來同步數據
既然 Non-Shareable 需要手動維護一致性,那它存在的意義和優勢是什么?
實際上,Non-Shareable 并不是沒有用,而是出于以下幾個考慮,它在某些場景下非常有意義:
? 一、性能更高
在多核系統中,如果你使用 Shareable memory(尤其是 SMP 系統中的 Inner Shareable):
- 每次訪問緩存行都可能觸發硬件級的 cache coherency 協議(如 MESI、MOESI 等);
- 這會引入額外的 總線/互聯傳輸負擔 和 延遲;
- 也可能導致 cache line bouncing,尤其當多個核頻繁修改同一個變量時。
而使用 Non-Shareable memory:
- 硬件默認只在當前核心訪問,不涉及其它核;
- 避免了不必要的 cache coherency 操作;
- 訪問更快,cache 命中率更高,延遲更低;
- 適合性能敏感、訪問頻繁、無需共享的私有數據。
? 二、明確分工與控制
Non-Shareable 強制開發者:
- 明確哪些內存區域是只在本核使用的;
- 哪些區域需要小心處理共享和同步;
- 有助于提升系統結構的清晰度和可維護性;
- 對一些實時性要求高的系統(RTOS)非常有用,避免因不必要的一致性導致時間不確定性。
2.2 Inner Shareable, and Outer Shareable
A region of Normal memory with the Shareable attribute is one for which data accesses to memory by different observers within the same shareability domain are coherent
——————《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
??具有 Shareable 屬性的 Normal memory 區域,其特點是:在同一共享域內的不同觀察者對該內存的數據訪問是一致的。
??在 ARMv7 架構中,可共享屬性(Shareability Attributes)用于定義一組觀察者(Observers),使得 data or unified caches 對特定訪問透明化。這些觀察者的集合被稱為可共享域(Shareability Domains),其具體行為由系統實現決定。以下通過示例說明其應用場景:
舉一個案例:
某虛擬內存系統架構(VMSA)的實現包含 two clusters of processors,需滿足以下要求:
- 對于每個 clusters :若數據訪問標記為 Inner Shareable,則集群內所有處理器的 data or unified caches 對該訪問透明(即緩存一致性自動維護)
- 兩個 cluster 之間:
- 僅標記為 Inner Shareable 的訪問無法跨集群維護緩存透明性
- 標記為 Outer Shareable 的訪問則能在兩個集群間實現緩存透明。此時,每個集群構成獨立的 Inner Shareable 域,而整個子系統屬于同一個 Outer Shareable 域。
若系統包含多個此類子系統,且子系統間的緩存互不透明,則每個子系統將形成獨立的 Outer Shareable 域。
為什么需要分層設計?
設置兩個層次的可共享性屬性(Inner Shareable 和 Outer Shareable)意味著系統設計者可以減少對于不需要參與 Outer Shareable 域的共享內存區域的性能與功耗開銷。
- 多級共享域的設計允許系統更靈活地控制共享粒度;
- 如果某塊內存只在一個 CPU cluster 內共享,就設置為 Inner Shareable,避免跨 cluster 的 coherency 同步開銷;
- 避免不必要的 Outer Shareable 標記 → 減少 coherency 機制觸發 → 更高效、節能。
In a VMSA implementation, for Shareable Normal memory, whether there is a distinction between Inner Shareable and Outer Shareable is IMPLEMENTATION DEFINED
——————《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
??需要注意的是,在 VMSA(虛擬內存系統架構)的實現中,對于 Shareable 類型的 Normal memory,是否區分 Inner Shareable 和 Outer Shareable 是由具體實現決定的(實現自定義)。
??對于 Shareable 類型的 Normal memory,Load-Exclusive 和 Store-Exclusive(即 LDREX/STREX)同步原語會考慮到同一 shareability 域內多個觀察者可能同時訪問該地址的情況
- ARM 的原子指令(如 LDREX/STREX)依賴于共享域概念;
- 若兩個核在同一 Inner Shareable 域內,它們的原子操作會被視為相關;
- 如果不在同一共享域中,它們可能不會觀察到彼此的修改 → 可能導致同步失敗。
??系統設計者可以使用 Shareable 屬性來指定哪些 Normal memory 區域需要具備緩存一致性的要求。但為了便于軟件移植,軟件開發人員不能因為某塊內存被標記為 Non-shareable,就假設多個處理器之間訪問該內存一定是非一致性的。
- 也就是說,Non-shareable ≠ 一定不一致;
- 有些系統中,Non-shareable 的內存可能也通過某種方式被多個核緩存一致;
- 所以不能依賴 Non-shareable 來推導“多個核訪問時不一致”的行為;
This architecture is written with an expectation that all processors using the same operating system or hypervisor are in the same Inner Shareable shareability domain
——————《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
本架構(ARMv7-A)假設:所有運行在同一操作系統或同一 hypervisor 下的處理器,屬于同一個 Inner Shareable 共享域。
2.3 Write-Through、Write-Back、Non-cacheable
??在 ARMv7 架構中,除了 Shareability(可共享性)(Outer Shareable / Inner Shareable / Non-shareable)之外,Normal Memory(普通內存) 還需要設置 Cacheability(緩存屬性),以決定 CPU 如何緩存該內存區域。
緩存屬性主要分為以下三種:
- Write-Through Cacheable.
- A cache in which when a cache hit occurs on a store access, the data is written both to the cache and to main memory.
This is normally done via a write buffer, to avoid slowing down the processor
- A cache in which when a cache hit occurs on a store access, the data is written both to the cache and to main memory.
- Write-Back Cacheable.
- A cache in which when a cache hit occurs on a store access, the data is only written to the cache. Data in the cache
can therefore be more up-to-date than data in main memory. Any such data is written back to main memory when
the cache line is cleaned or reallocated. Another common term for a write-back cache is a copy-back cache
- A cache in which when a cache hit occurs on a store access, the data is only written to the cache. Data in the cache
- Non-cacheable
- 這個比較好理解,就是內存不帶 cache,即對這塊內存的訪問,不會經過 cache
In some cases, the use of Write-Through Cacheable or Non-cacheable regions of memory might provide a better mechanism for controlling coherency than the use of hardware coherency mechanisms or the use of cache maintenance routines
——————《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
??在某些情況下,使用 Write-Through 緩存策略或 Non-cacheable 的內存區域,可能比依賴硬件緩存一致性機制或緩存維護指令,更適合作為控制一致性的一種機制。用合理的緩存策略(Memory Attributes)來“避免麻煩”,可能比“處理麻煩”更好。
3、 Device and Strongly-ordered memory
3.1 概念
??在 ARMv7 架構中,設備內存(Device Memory) 和 強序內存(Strongly-ordered Memory) 通常用于映射內存映射外設(Memory-mapped Peripherals) 和 I/O 地址空間(I/O Locations)。
System peripherals will almost always be mapped as Device memory.
——————《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》
??對于處理器顯式訪問標記為 Device 或 Strongly-ordered 的內存區域,需遵循以下規則:
- 訪問大小嚴格匹配程序定義:所有訪問必須按照程序中指定的數據寬度(如 8 位、16 位、32 位)執行,不可拆分或合并。
- 對 Device/Strongly-ordered 內存的每次訪問(如 STR/LDR)必須作為一個完整單元執行。例如,32 位寄存器寫入不可拆分為兩個 16 位寫入。
- 訪問次數嚴格匹配程序定義:訪問次數必須與程序指定的次數一致,不可因優化而增減。
- 編譯器/硬件不得對這類內存進行訪問合并(如合并相鄰寫操作)或冗余訪問消除(如省略重復讀操作)
硬件實現限制:
除非由于異常(Exception)(如中斷、缺頁)導致額外訪問,否則處理器不得對 Device 或 Strongly-ordered 內存執行比程序順序執行所規定的更多訪問。本節將討論異常對訪問行為的允許影響。
從上面這些分析可以看出,ARMv7 對 Device/Strongly-ordered 內存的嚴格訪問規則,確保了硬件寄存器和關鍵 I/O 操作的可預測性
下面再總結下,Device and Strongly-ordered memory 的一些特性:
- The architecture does not permit speculative data accesses to memory marked as Device or Strongly-ordered
- The architecture does not permit unaligned accesses to Strongly-ordered or Device memory
- Address locations marked as Device or Strongly-ordered are never held in a cache
- In the ARMv7 architecture, the core can re-order Normal memory accesses around Strongly-ordered or Device memory accesses
3.2 Device and Strongly-ordered 區別
第一個區別就是共享域的區別:
- a region of Device memory can be described as one of
- Outer Shareable Device memory.
- Inner Shareable Device memory.
- Non-shareable Device memory
- Strongly ordered memory regions are always shareable
關于 shareable,ARMv7 手冊中有這樣一段描述:
ARM deprecates the marking of Device memory with a shareability attribute other than Outer Shareable or Shareable. This means ARM strongly recommends that Device memory is never assigned a shareability attribute of Non-shareable or Inner Shareable
——————《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》
??ARM 不建議你對 Device memory 設置為除了 “Outer Shareable” 或早期架構中通用的 “Shareable” 之外的任何 shareability 屬性。尤其要避免使用 “Inner Shareable” 或 “Non-shareable”。
第二個區別就是完成時的區別:
The only architecturally-required difference between Device and
Strongly-ordered memory is that:
- A write to Strongly-ordered memory can complete only when it reaches the peripheral or memory component accessed by the write.
- A write to Device memory is permitted to complete before it reaches the peripheral or memory component accessed by the write.
??上面這個說法是官方的意思,我理解一下,應該是 Strongly-ordered 不惜犧牲性能,去做保序的要求,一定要實際訪問到外設,而 Device 類型的訪問指令,可能還在路上(流水線中);
4、總結
4.1 關于 Inner Shareable, and Outer Shareable 的疑惑
??關于 Inner Shareable, and Outer Shareable 屬性,初學者經常會疑惑,這兩個屬性是從什么角度去定義的?從上面的分析來看,是從 cahce 一致性角度來定義的?直接上結論:
??Shareable 確實和 cache 一致性密切相關。但 Shareable 的概念并不僅限于 Normal memory,它是一種通信語義或訪問語義的定義,用來告訴處理器系統(包括緩存子系統、互聯、總線和外設)這個區域是否可能被多個觀察者訪問。
??例如,Device 類型的 memory,雖然不帶 cache,但是也有 Inner Shareable, and Outer Shareable 屬性。
- Device memory 是不能被緩存的,所以 Shareable 與否不會影響緩存行為。
- 但是在 Barrier(內存屏障)語義中,Shareable 的 Device memory 和 Non-shareable 的 Device memory 是不一樣的:
DMB
等指令中的 Shareable,就是在說:“這個屏障要作用于 Shareable 范圍內所有可能看到這個地址空間的主體。”- 比如 CPU 和 DMA 共享一個外設寄存器區,這個區域應該標記為 Device + Shareable,這樣
DMB
可以保證這些外設訪問的順序一致性。
ARM 中的內存屏障指令 DMB
#define dma_wmb() dmb(oshst)
#define __smp_wmb() dmb(ishst)
- ISHST
DMB operation that waits only for stores to complete, and only to the inner shareable domain - OSHST
DMB operation that waits only for stores to complete, and only to the outer shareable domain
??我們要明白,Shareable 并不等于“能被多個主體訪問”,而是告訴系統:這個 memory 區域的訪問順序、一致性、barrier 等行為可能涉及多個 observer,系統必須尊重這點。
4.2 注意項
??有一點非常重要:內存類型(如 Normal、Device、Strongly-Ordered)并不會對整個指令流的執行順序產生可靠影響,它們只對內存訪問的順序產生影響。
- 指令的執行順序 ≠ 內存訪問的順序
- 內存類型(如 Device、Normal)只能控制 load/store 的順序
- 想要確保 某個寫操作之后再執行某條指令 → 你得用 DMB, DSB, ISB 這類內存屏障指令
- 千萬不要以為 “把內存設成 Strongly-Ordered,就等于所有指令順序都被保留了” ——這只是內存訪問順序的保證,不是執行語義的全局保證