缓存抖动(Cache Thrash)指的是 Cache 不断地进行逐出和读入的行为。这种行为一旦发生,Cache 优化内存带宽的效果就不存在了,Cache 会频繁读写内存。缓存抖动也叫做 “Cache 乒乓效应”。

造成 cache thrash 的原因是多样化的。最直观的就是 cache 过小,如果 CPU 希望读取一个很大的数据,那么 cache 就会为了这个数据逐出其他的数据,而被逐出的数据可能还会用到,那么 cache 就需要再次从内存中读入,而读入又会导致其他的数据从 cache 中被逐出。颇有一种“拆东墙补西墙,顾脑袋顾不了屁股”的美感。

还有一种造成 cache thrash 的原因是由 cache 一致性导致的。如果一个变量在多个核心的 cache 中存在,当这个变量被多个处理器核频繁访问时,处理器核之间频繁地互相剥夺对一个共享块的访问权(同时只能有一个处理器核心的 cache 被写)就会导致性能严重下降。也构成了一种缓存抖动现象。

更严重的是,有可能并不是真的存在一个“共享变量”被多个处理器核心访问,而是只存在一个“共享 cache line”,这个 cache line 上可能有多个不相关变量,分别被不同的处理器核心修改,但是因为它们在同一个 cache line 上,所以各个核心依然会频繁互相剥夺它们的独占权。这种现象被叫做“伪共享”。

有一个非常著名的例子是锁,因为锁一定是共享的,而且争锁的时候 lock 的 cache line 会在争锁时反复在多个 core 的 cache 里移动,导致性能开销大。这里有一个 例子