zl程序教程

您现在的位置是:首页 >  后端

当前栏目

图解Cache | 一个月代码白写了

图解代码 cache 一个月
2023-06-13 09:17:41 时间

我是cloud3

本文是图解系列之Cache

谈起高速缓存大家肯定了解

不了解也很正常

因为它设计在CPU里

一般你不能直观的接触它

但是今天说些它和我们紧密相关的事情

就是CPU Cache对写代码的影响

首先看几个例子

A:

B:

那么cache是如何影响这2段code的呢?

根据Cache局部性和连续性原则:A例子中当访问第一个访问变量时,会发生一次cacache miss,此时CPU会把后面连续的一段内存load到cache line中,继续往下执行会一直cache hit,直到访问到cache line的结尾再次cacache miss,然后再次一直cache hit,由此往复到完毕。

总结起来这种写法cache命中率很高。

B例子中变量是跳跃的访问的,在cache比较小时,cache命中率极低。

用一个极端的图来感受一下两者的区别:

A:

B:

结果也是符合我们预期的:

运算时间后者是前者的1.8倍。

另一个例子

A:

B:

A中对同一个变量,一个线程写,一个线程读,因为两个线程调度在不同的CPU上,硬件会有大量cache同步动作。

B中两个线程读写的是不同的变量,就没有硬件cache同步开销。

结果也是符合我们预期的:

运算时间前者是后者的1.5倍。

发散

还有很多例子,在此再说一个比较常用的。

#define CACHE_LINE  32
struct S1 {int a, b, c, d;} __attribute__ ((aligned(CACHE_LINE)));

上面这段声明是使用数据对齐支持来优化缓存行的使用。

这种方法是将经常一起使用到的小对象放到一个结构体中,并强制使用缓存行大小对齐。

这样可以有效地保证每个小对象被访问时其他小对象也同时被load到缓存中,从而产生显著的性能优势。否则可能这些变量会落到不同的cache line中,降低命中率。

上述数据对齐提高cache命中率在windows下有类似的方式:

#define CACHE_LINE  32
__declspec(align(CACHE_LINE)) struct S1 {int a, b, c, d;};

通过以这种方式声明变量,编译器可确保变量分配在同一缓存行上。

关于理解Cache对写代码的重要性本文就讨论到这里。

如果感觉有用,记得点个赞】。

我是cloud3

本文是图解系列之Cache