
1. 问题背景
开篇老规矩,"小T三问":
- 你知道什么是Cache False Sharing吗?
- 你知道False Sharing在多核MCU上不仅仅是性能问题,更会导致变量被莫名篡改吗?
- 你知道如何在AUTOSAR多核工程中彻底规避这个问题吗?
这篇,我们来一起探索并回答这些问题。
在R5F等双核MCU的AUTOSAR项目中,小T遇到过一个极其诡异的bug:Core0明明没有写Core1的变量,但Core1的变量值却被莫名其妙改掉了。 逻辑查了无数遍,锁也没问题,最终定位到罪魁祸首——Cache False Sharing。
2. 什么是Cache False Sharing?

CPU的Cache以Cache Line为最小操作单位(R5F一般为32字节)。当两个核的变量恰好落在同一条Cache Line中时:
- Core0修改自己的变量 → Core0的Cache Line标记为dirty
- Core0的Cache Line回写到RAM → 整条32字节全部回写
- 此时Core1也修改了自己的变量,但还在Cache中未回写
- Core1的Cache失效后重新从RAM加载 → Core1刚写的值被Core0回写的旧值覆盖!
这不是性能问题,这是数据被篡改!
3. R5F双核实战复现
以TI TDA4/AM263x的R5F双核为例,假设如下代码:

故障现象:
- Core0在10ms任务中递增
g_Core0_Counter
- Core1在5ms任务中更新
g_Core1_Status为当前通信状态
- 实际运行中,Core1发现
g_Core1_Status会间歇性跳变回旧值
- 加断点调试反而不复现(因为调试器会刷新Cache)
根本原因: Core0写g_Core0_Counter后Cache Line回写RAM,把Core1还没来得及回写的g_Core1_Status旧值也一并写回,Core1的新值被覆盖。
4. 解决方案
方案一:Cache Line对齐(推荐)

方案二:分配到各核私有RAM
在Linker Script中将各核变量隔离到独立内存段:

各核使用TCM(紧耦合内存)访问自己的变量,TCM不经过Cache,从根源上消除问题。
方案三:共享变量使用Non-Cacheable区域
对于必须跨核共享的变量,在MPU中将对应内存区域配置为Non-Cacheable:

5. 小T心得
- Cache False Sharing在多核MCU上不只是性能问题,更是数据一致性问题,变量会被莫名篡改,而且极难复现和定位;
- 凡是多核工程中出现"变量莫名跳变"、"加断点就不复现"的现象,第一时间检查变量的Cache Line对齐情况;
- 养成习惯:多核共享或各核独立的全局变量,定义时就加
aligned(32),几个字节的padding换来的是系统稳定性;
- 能用TCM就用TCM,能配Non-Cacheable就配Non-Cacheable,不要让Cache成为多核协作的隐形杀手。
-end-
评论区
登录后即可参与讨论
立即登录