cache line

  1. 一个L1 DATA CACHE相当于一块小的内存,我们假设它为16K大,它会与一般物理内存交互。   
  2. 它和内存交互一般一次传输16个字节(32个字节),也就是:   
  3.   
  4.   
  5. CACHE 字节0-15一次写到/读取物理内存 ,字节16-31一次写到/读取物理内存.32-47 ... ...   
  6.   
  7. 这些一次被传输的字节被称为cache line。   
  8. --------------------------------------------------------------   
  9.   
  10. 另外,cache写到物理内存的位置不是任意的,   
  11. 我们假定内存为64K,那么cache地址0的数值只能和物理内存的地址0, 16K, 32K交互;cache地址1的数值只能和物理内存的地址1, 16K+1, 32K+1交互   
  12. 。。。 。。。cache地址16K-1的数值只能和物理内存的地址6K-1, 16K+16K-1, 32K+16K -1交互   
  13.   
  14. 这说明了两点:   
  15.   
  16. (1)假设对象A的一个字段长为16个字节,如果它放在物理地址 0-15,那么它将和cache的第一个cache line 交互,如果放在物理地址 8-23,那么   
  17. 如果CPU要访问这个字段,必须将第一个和第二个cache line 都读入,才能获得这个字段的信息,显然这样速度慢,所以一般字段需要cache line对齐,   
  18. 在这里就是16个字节对齐。   
  19.   
  20.   
  21. (2)关于colour   
  22.   
  23.   
  24. 一般一个对象某些字段访问频繁些。   
  25. 假定一个cache(这个cache指slab的cache,不是上面提到CPU的L1 DATA CACHE)占用5个页面也就是20K.   
  26. 假定其中对象大小为32个字节,前16个字节访问频繁许多。   
  27.   
  28. 假定对象A起始于物理地址0,对象C起始于31,对象B起始于物理地址16K,那么对象A,对象B的前16个字节都和第一个cache line 交互,后16个字节都和第二个cache line 交互   
  29. 对象C前16个字节与第3个cache交互。   
  30.   
  31. 我们假定内核访问A后就访问B,再访问A,交错进行,并且前16个字节次数都是50次,后16个为10次。C也是。   
  32.   
  33. 这样第一个cache line 要交互100次,第二个20次,一共120次。   
  34.   
  35. 如果让对象B向后移动16个字节,也就是对象B的前16个字节与第二个cache line 交互,后16个与第3个交互。   
  36. 那么第一个为2次,因为只有开头结尾2次要与内存交互,其它每次都在L1 DATACACHE 中写就可以了。第2个cache line为20次左右(后面的只须在CACHE中读写),第3个cache line为20次,   
  37. 3个line一共才41次,你不妨仔细模拟一下。   
  38.   
  39. 所以进行错位能降低CACHE的交互次数,从而提高CPU处理速度能力。   
  40.   
  41. 这个错位(也就是上面的16个字节)就是colour.  

随着计算机的飞速发展,虽然内存变得越来越大,但是在速度上面却跟不上cpu的发展。为了保证系统整体性能,cache的地位变得越来越重要。

Cache的原理很简单,就是根据程序访问的局部性,把最近访问过的数据或者程序缓存在一块速度更快的内存中。
现在的cache命中率一般都会超过90%,这样就解决了 越来越快的cpu和 越来越大却相对慢的内存之间的配合问题。

为了完成这个任务,简单的方法就是把cache分成许多行(line),每一行分为两部分,一部分是Data,保存缓存的数据,另一部分是Tag,保存这这些数据在内存中的地址信息。每行之间没有关系,这样每次cpu访问的时候,把地址给每一行的tag进行比较,如果有相同即为命中。这就是“全相联Cache ”。
这种方式的缺点是,每次内存访问都要跟每一行的tag进行比较,造成结构上的复杂。
假设cache大小为64KB,每一行的data是32B,那么就有2048 line, 一次内存访问要跟每一个line的tag进行比较,才能确定是否命中,显然太复杂了。

为了解决这个问题,就对其进行改进,改进的结果就是直接映像Cache。 这种方式把访问内存的地址分为3个部分。高位地址,低位地址,和行内部地址。比如,地址为32位,cache大小为64KB, 每行的data大小为32B。
那么地址位如下分配:
高位地址范围为:[31-16], 低位地址范围为[15-5], 行内部地址范围为[4-0]
比如:对于地址 0x12345678, 0x1234为高位地址, 0x567 >> 1 为低位地址, 0x18为行内地址
在访问该内存的时候,首先用低位地址作为行号来检索 0x567 >> 1 = 0x293 就是第659行cache,找到这行cache用0x1234与其tag内的地址比较,相等则命中。

很显然这种结构,非常简单,只需要跟一行进行比较就可以了。不过,它的缺点是每一行对应内存中很多不同的地址,而且这些地址只能缓存在这一行中。
比如,当上面那个地址缓存了之后,我们又要访问地址0x43215678, 这时候还是找到第659行cache,但是只能将0x12345678的数据作废,重新读入新地址的数据。如果,这种情况频繁发生,会大大降低系统效率。

为了解决这个问题就出现了改进的“组相联Cache“,组相联Cache 把cache分成几个独立的组。这样,虽然一个line可以对应内存中的很多地址,但是内存的这些地址可以存在不同的组中,这样碰到上述那种情形的概率就非常低了。

举个例子:64K cache分为4组,每组16K,每行32B,每组就有512行。
那么地址分配方式就变为:
高位地址范围为:[31-14], 低位地址范围为[13-5], 行内部地址范围为[4-0]
0x12345678 地址就对应到一组中的第147行,虽然地址0x43215678也对应在147行,但是他们可以分别存放在4组中的任意两组而互不影响。从效果上,和全相联Cache基本相当,却在结构上简单很多。所以,是当前常用的方式。

最近,需要用到cache看了一些介绍,做个简单的笔记。
这是一个基本的工作原理,实际上的cache要复杂的多,比如 write-through和write-back问题,cache aliases问题等等,而且不同的cpu cache的配置方式也各不相同,以后有机会再详细记录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值