CMN基础架构:CMN-600/700总线拓扑、Mesh网络与一致性协议简介
好,我们直接进入正题。CMN-600和CMN-700,说白了就是ARM用来把多个CPU核、GPU、NPU这些东西粘在一起的“交通网络”。你想想看,一个SoC里几十个核同时跑,数据怎么传?谁先谁后?这就是CMN要干的事。
我个人习惯把CMN理解成一个“超级立交桥”。它不负责计算,只负责把数据从一个地方搬到另一个地方,而且要搬得快、不打架、不出错。
一、总线拓扑:从“单车道”到“网格”
早期的总线,比如AXI,就像一条单车道。所有设备都挤在这条路上。车多了就堵。CMN-600开始,ARM换了个思路——用Mesh网络。
Mesh网络是什么? 你可以想象成一个棋盘。每个CPU核、每个内存控制器,都放在棋盘的一个格子里。格子之间横着竖着都有路。数据从A点到B点,可以走多条路径。一条路堵了,换一条。
我在项目中遇到过一个问题:某个客户的设计里,CPU核和内存控制器离得太远,跨了4个Mesh节点。结果延迟高了30%。后来我们把关键路径上的节点做了“直连”优化,才压下来。嗯,这里要注意:Mesh不是万能的,布局布线时一定要看“热点”在哪里。
核心要点: CMN-600/700的Mesh网络,本质是一个2D的、基于X-Y路由的片上互联结构。每个节点叫“Crosspoint”,负责转发数据包。
CMN-700相比CMN-600,主要改进是:
- 支持更多的节点(最多256个)
- 增加了“低延迟路径”的硬件支持
- 对QoS(服务质量)的粒度更细了
说白了,CMN-700就是把路修得更宽,红绿灯控制得更智能。
二、Mesh网络:数据怎么走?
数据在Mesh里走,用的是“数据包”的形式。每个包包含目标地址、源地址、数据内容。每个Crosspoint节点收到包后,先看目标地址在哪个方向,然后决定往X方向走还是Y方向走。
这里有个经典问题:死锁。如果所有数据都先走X再走Y,万一某个节点堵住了,后面的包全卡死。CMN怎么解决?它用了“虚拟通道”(Virtual Channel, VC)。
我建议你记住这个:VC是CMN避免死锁的核心机制。每个物理通道被拆成多个虚拟通道,不同类别的数据走不同的VC。比如,请求走VC0,响应走VC1。这样即使请求堵了,响应还能走。
避坑指南: 我曾经在一个项目中,因为VC配置不当,导致高优先级的中断请求被低优先级的DMA写操作堵住。排查了三天才发现是VC映射错了。后来我养成了一个习惯:所有关键中断请求,必须走独立的VC。
另外,Mesh网络的延迟不是固定的。它取决于跳数(hop count)。从节点A到节点B,每经过一个Crosspoint,就增加一个时钟周期的延迟。所以,布局时把经常通信的模块放近一点,能省不少时间。
三、一致性协议:数据不能“打架”
多核系统最头疼的问题是什么?数据一致性。两个核同时读写同一个内存地址,谁的数据是对的?
CMN用的是MESI协议的变种,叫MOESI。每个缓存行有5个状态:
| 状态 | 含义 | 说明 |
|---|---|---|
| M | Modified | 数据被修改,且只在本缓存中 |
| O | Owned | 数据被修改,但其他缓存也可能有副本 |
| E | Exclusive | 数据只在本缓存中,且与内存一致 |
| S | Shared | 数据在多个缓存中,且与内存一致 |
| I | Invalid | 数据无效 |
你可能会问:为什么需要“O”状态?嗯,这是为了减少不必要的内存写回。当数据被修改后,如果另一个核要读,直接从拥有“O”状态的核拿就行,不用等内存更新。这在多核场景下能省不少带宽。
CMN的一致性协议,是通过“Snoop过滤器”来实现的。每个Mesh节点里都有一个Snoop Filter表,记录着每个缓存行在哪些核里有副本。当某个核要写一个地址时,先查Snoop Filter,然后向所有持有该地址的核发“无效化”请求。
注意: Snoop Filter的大小是有限的。如果缓存行太多,Snoop Filter会溢出,退化成广播模式——向所有核发请求。这会导致性能急剧下降。我在调试一个16核系统时,就遇到过Snoop Filter溢出,性能直接腰斩。后来我们通过调整页着色(Page Coloring)来减少冲突,才解决。
四、框架图:CMN-700核心结构
下面我用SVG画一张CMN-700的简化结构图,帮你把上面说的内容串起来。
这张图里,每个绿色方块是一个Crosspoint节点。黄色的是带Snoop Filter的节点。CPU、GPU、NPU挂在Mesh上,内存控制器(DMC)也挂在Mesh上。数据从CPU到内存,要经过若干跳的Crosspoint转发。
五、小结:记住这三句话
- Mesh网络:用棋盘格的方式连接所有节点,数据走X-Y路由,用虚拟通道避免死锁。
- 一致性协议:MOESI状态机 + Snoop Filter,保证多核看到的数据是一致的。
- 性能关键:布局决定延迟,Snoop Filter大小决定一致性开销。
我个人觉得,理解CMN最好的方式就是动手画一画数据流。你想想看,一个读请求从CPU发出,经过几个Crosspoint,到达内存控制器,再返回数据。每一步的延迟是多少?哪里可能成为瓶颈?想清楚这些,你就能针对性地做优化了。
最后一句经验之谈: 别把CMN当成黑盒。虽然ARM提供了很多配置选项,但真正调优时,你得知道每个寄存器控制的是哪个Crosspoint、哪条VC。我曾经因为一个QoS寄存器配错,导致整个系统的实时任务抖动。后来我养成了习惯:每次改配置前,先画数据流图,标出关键路径。
公众号:蓝海资料掘金营,微信deep3321