CPU性能优化学习记录

最近复习Java开发,这里记录一下cpu缓存相关知识

 

这里引用大神博客,做一下知识分享,如果涉及侵权,请联系我,我会立马删除。

 

CPU性能优化学习记录

在内存与cpu寄存器之间,还有一块区域叫做cpu高速缓存,即我们常常说的cache。

cache分为L1、L2、L3三级缓存,速度递减,离cpu越来越远,L1、L2每个内核自己都有,L3是每个插槽上的多个内核共用一个。L1缓存的缓存容量通常在32-4096KB。cpu按照值使用频道来从1、2、3缓存逐个进行检索,L1如果没有命中,就向下继续检索L2、L3直到内存。下表访问速度表:

 

 

从CPU到 大约需要的CPU周期 大约需要的时间(单位ns)
寄存器 1 cycle  
L1 Cache ~3-4 cycles ~0.5-1 ns
L2 Cache ~10-20 cycles ~3-7 ns
L3 Cache ~40-45 cycles ~15 ns
跨槽传输   ~20 ns
内存 ~120-240 cycles ~60-120ns

 

多CPU读取同样的数据进行缓存,进行计算后会以那个CPU为主,这时候为

了保证每个缓存一致性;引出缓存一致性协议;

MESI(Modified Exclusive Shared Or Invalid)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出)是一种广泛使用的支持写回策略的缓存一致性协议。

CPU中每个缓存行(caceh line)使用4种状态进行标记(使用额外的两位(bit)表示):

M: 被修改(Modified)

该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该缓存行中的内存需要在未来的某个时间点(允许其它CPU读取请主存中相应内存之前)写回(write back)主存。

当被写回主内存之后,该缓存行的状态会变成独享(exclusive)状态。

E: 独享的(Exclusive)

该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态shared)。

同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。

S: 共享的(Shared)

该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。

I: 无效的(Invalid)

该缓存是无效的(可能有其它CPU修改了该缓存行)。

 

CPU指令运行时指令重排:当cpu写缓存的时候发现缓存区域被其他cpu占用,为了提高cpu的处理性能,可能会将后面的读缓存命令优先执行;提高整体读写速度。遵循as-if-serial 语义;

 

内存屏障:为了保证内存和缓存中数据保持一致 

写内存屏障:在指令后插入Strore Barrier ,把写入缓存数据更新写入主内存,保证其他线程可见;

读内存屏障:在指令前插入Load Barrier ,可以让告诉缓存的数据强制失效,强制重新从主内存中加载数据;

 

一般来说,缓存失效有三种情况:

1  第一次访问数据, 在cache中根本不存在这条数据, 所以cache miss, 可以通过prefetch解决。

2 cache冲突, 需要通过补齐来解决(伪共享的产生)。

3 cache满, 一般情况下我们需要减少操作的数据大小, 尽量按数据的物理顺序访问数据