Cache伪共享(False Sharing)问题浅析

1.问题

CPU的Cache以Line为单位与内存交换数据。对于代码中位置相近的变量,比如:

long a;

long b;

其在Cache中可能被放置在同一个Line中。在两颗CPU频繁访问不同变量的情况下,容易出现因为同一Line内容频繁做状态同步导致的性能下降问题,这个问题就称之为Cache伪共享问题。

举个例子,比如上面的两个变量。如果CPU0上的线程频繁使用变量a,CPU1上的线程频繁使用变量b,那么根军缓存一致性协议MESI,这个Line在不同CPU的Cache上进行同步的代价是很高的。

2. 分析

还是以第一部分的例子来分析。

初始状态,包含变量a和b的Line只存在于CPU0的缓存中。CPU0上的Line状态为E。

CPU1要对变量b写入,该Line被读入CPU1的Cache中。这时CPU0和CPU1该Line的状态都是S。因为CPU1要写入,写入后CPU1上的Line变为M,而CPU0上该Line同步更新状态为I。

之后CPU0要对变量a写入,CPU1上该Line内容会先写入内存,然后更新为I。CPU0对a写入后,CPU0上该Line的状态变为M。

再之后两颗CPU上频繁的对自己需要的变量进行访问和写入,该Line的状态会来回在M和I之间摆动。背后的代价是CPU之间频繁的发送总线读写消息进而使得程序运行效果变差。

3. 解决

如果开发面临类似的问题,主要是将两个变量之间“隔开”距离,使得它们不会被缓存在同一Line中。

可以使用编译器的align标签。如果是结构体,也可以在结构体size不到一个Line size(一般是32或64字节)的时候在结构体中添加一些字段,让两个结构体“隔开”。

4. 工具

Perf c2c命令可以检查这类情况。笔者开发中用的比较少,感兴趣的读者可以自行查找相关信息,网上相关资料非常多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值