• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

内存类型Normal Non-cacheable Bufferable详解

好的,我们来深入剖析 AXI 协议中一个非常实用且常见的内存属性:Normal Non-cacheable Bufferable。

这个属性是性能与一致性之间一个经典的、精心设计的权衡。理解它对于设计高性能的嵌入式系统和驱动至关重要。

核心结论先行

  • 是什么: 这是一种用于普通内存(Normal Memory) 的属性,它要求访问不经过缓存,但允许写操作被缓冲。
  • 目标: 在保证数据最终一致性(所有访问者最终都看到相同数据)的前提下,显著提升写入性能。
  • 核心价值: 它是DMA缓冲区和共享内存区域的理想选择,因为它避免了缓存一致性的开销,同时通过写缓冲隐藏了相对缓慢的内存写入延迟。

详细解析

1. 属性定义:AxCACHE = 4‘b0001

让我们分解这个信号:

  • Non-cacheable (C=0):

    • 这是根本。该事务绝不能与缓存(Cache)发生任何关系。
    • 读操作必须从主内存(DDR)获取数据。
    • 写操作的目标是主内存(DDR)。
    • 这确保了所有总线主设备(CPU, DMA, GPU等)看到的都是内存中的同一份数据,避免了缓存一致性(Cache Coherency)的复杂问题。
  • Bufferable (B=1):

    • 这是关键所在,也是性能提升的来源。
    • 它允许写操作被放入一个写缓冲区(Write Buffer) 中。
    • 发起写操作的主机(如 CPU)可以立即得到一个“完成”响应,然后继续执行后续指令,而无需等待数据真正穿越系统互联并物理写入 DDR。
    • 写缓冲区会异步地、在后台将数据最终完成到内存中。
  • Non-allocate (RA=0, WA=0):

    • 自然不会分配缓存行。

2. 内存类型:Normal

再次强调,这个属性的目标是 Normal Memory 区域(如 DDR)。这意味着:

  • 无副作用: 多次读取同一地址不会改变数据本身。
  • 允许重试: 如果访问失败,可以安全地重试。
  • 访问顺序相对灵活: 系统互联可以对访问进行优化和重排序,只要最终结果符合内存一致性模型。

行为与工作原理

写操作流程(CPU Perspective):

  1. CPU 执行一条存储指令(如 STR),目标地址被标记为 Normal Non-cacheable Bufferable。
  2. 数据被 CPU 的总线接口单元放入写缓冲区。
  3. 几乎立即,CPU 收到一个“写入成功”的确认。CPU 的流水线可以继续流动,不会因为这次内存写入而停滞。
  4. 在后台,写缓冲区负责将数据通过 AXI 互联发送到内存控制器,最终写入 DDR。这个过程对 CPU 是透明的。

读操作流程:

  1. CPU 执行一条加载指令(如 LDR),目标地址是 Normal Non-cacheable。
  2. 由于是 Non-cacheable,请求会直接发送到内存控制器。
  3. CPU 必须等待数据从 DDR 读取并返回。读操作不能被缓冲(缓冲读会引入陈旧的旧数据),因此读延迟是真实的。

为什么需要它?—— 性能与一致性的完美权衡

这是一种“鱼与熊掌兼得”的策略:

  1. 避免缓存一致性开销 (Non-cacheable 的好处):

    • 当多个主设备(如 CPU 和 DMA)共享一块内存时,如果 CPU 缓存了该内存,就需要复杂的缓存一致性协议(如硬件嗅探)来保证数据同步,这会消耗总线带宽和功耗。
    • 直接标记为 Non-cacheable,就彻底避免了这个问题。所有设备都直接读/写 DDR,数据视图天然就是一致的。这是一种简单而有效的共享方案。
  2. 提升写入性能 (Bufferable 的好处):

    • 写入 DDR 的速度远慢于 CPU 的执行速度。如果每次写都要等 (Non-bufferable),CPU 会花费大量时间“空转等待”。
    • Bufferable 允许 CPU“ fire-and-forget”(发射后不管),将数据扔进写缓冲区后就去干别的事情,极大地隐藏了内存写入延迟,提高了 CPU 的利用率和系统整体吞吐量。

典型应用场景

  1. 理想的 DMA 缓冲区:

    • 场景: 网卡接收数据包。CPU 需要分配一块内存给网卡(DMA)存放收到的数据。网卡写完数据后,需要通知 CPU 来处理。
    • 为什么是它:
      • Non-cacheable: 确保了 CPU 去处理数据时,直接从 DDR 读取,看到的是网卡 DMA 写入的最新数据,而不是自己缓存里的旧数据。
      • Bufferable: 当 CPU 要配置 DMA 或更新缓冲区描述符时,写入操作可以被缓冲,CPU 无需等待,从而能更快地响应网卡和处理其他任务。
  2. 大量数据初始化:

    • 场景: 清零一块大内存、或向帧缓冲区(Frame Buffer)填充图像数据。
    • 为什么是它: 顺序写入大量数据是 Bufferable 属性最能发挥优势的地方。CPU 可以以最高速度连续发出写操作,只需关心写缓冲区是否满,而无需关心 DDR 的实际写入速度。
  3. 多核间通信的共享内存:

    • 场景: 两个CPU核心通过共享内存传递消息。
    • 为什么是它: Non-cacheable 保证了一个核心写入的数据,另一个核心能立刻看到(因为都在直接访问DDR)。Bufferable 允许写入方核心高效地执行写入操作。

潜在风险与注意事项

  • 数据可见性的延迟: “写入完成”并不代表数据真的在DDR里了,只代表它在写缓冲区里。如果另一个主设备(如DMA)在数据从写缓冲区刷到DDR之前就去读取,它可能会读到旧数据。
  • 解决方案: 这就需要内存屏障(Memory Barrier) 指令(如 ARM 的 DMB 或 DSB)。在 CPU 通知其他设备“数据已就绪”之前,必须插入一个屏障,确保所有在屏障之前的缓冲写操作都已经真正完成到内存中。

示例:

// CPU 准备数据给 DMA
*(volatile uint32_t*)dma_buffer = data; // Bufferable write, goes to write buffer
// ... more bufferable writes ...

DSB(); // Data Synchronization Barrier: Flushes the write buffer, waits for all writes to complete

// Now it's safe to tell the DMA engine that the data is ready
*(volatile uint32_t*)dma_status_reg = DMA_GO; // This should be a Device write

对比总结

属性 AxCACHE 读操作 写操作 优点 缺点 适用场景
Normal Non-cacheable Bufferable 4‘b0001 直达内存,慢 可缓冲,CPU立即继续 高性能共享,避免缓存开销 需屏障保证最终可见性 DMA缓冲区、共享内存、大数据块操作
Normal Non-cacheable Non-bufferable 4‘b0000 直达内存,慢 直达内存,CPU等待 写操作立即可见 性能差 对写完成有即时要求的严格共享数据
Normal Write-Back Cacheable 4‘b1111 高速缓存命中 写回缓存 极致性能 缓存一致性开销大 处理器私有代码和数据

总结

Normal Non-cacheable Bufferable 是 AXI 协议中为共享内存场景设计的高性能实用属性。

  • 它的设计哲学: 通过 Non-cacheable 保证多设备数据视图的最终一致性,同时通过 Bufferable 来最大化写入操作的效率。
  • 它的适用场景: 几乎是设备DMA操作和核间通信的标准配置。
  • 对程序员的要求: 开发者必须意识到写操作的异步性,并在需要保证数据全局可见性的关键点,主动使用内存屏障指令来同步操作。

posted on 2025-09-15 21:59  SOC验证工程师  阅读(9)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3