我是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