Stream buffer是一个用于在cache和memory或者L1cache和L2cache之间的预取器,相应地,其目的是用于替代L2cache或者减少L1cache的缺失率
最原始的streambuffer由Jouppi(见参考论文)一个人提出(牛逼吧?论文上也是一个作者),用于在L2和L1cache之间预取数据,后来被Palacharla引申,用于在cache和memory之间预取数据,主要目的是代替L2cache。
一.简单介绍stream buffer原理:
Cache miss后如果在stream buffer中查到了相应的数据,则处理器把这个cache block取到cache中。如果遇到cache写回,则bypass stream直接写回,并且把在stream中对应的数据invalidate掉。
与二级cache对比,streambuffer的硬件逻辑很少,每一个stream buffer需要一个comparator、一个adder、一个小的SRAM用于存储cache block。另外,由于没有RAM查询操作,所以访问stream buffer比访问二级cache快。
由于大部分程序在同一个循环中会访问多个数组,所以可以考虑同时使用多个stream并行预取多组数据。每次发生cache miss,把地址与每个stream的头部tag进行对比,如果命中了其中某个stream,那么就把该cache block预取到cache中。Stream个数少于8个时都不会增加访问时间。
对于streambuffer重要的两个参数是streams的数量和每个stream的深度。深度是指每个stream预取的entry的个数。
Stream buffer的工作过程:为了避免不必要的预取,在stream buffer中使用过滤器(filter),其实现过程是:如果对于cache block的引用i发生了miss,并且对于i+1的引用也发生了miss,那么就分配一个stream用于预取i+2,i+3,等等。其实现过程如下图所示:
1. 保持一个N项的history buffer,其中存放的是最近发生miss的地址的下一个地址,例如a地址发生miss,则把a+1存放到该buffer中。
2. 把每一个在L1cache中发生miss、并且在stream中也miss的地址,与history buffer做比较,如果命中,则说明最近的两次访存是a,a+1,那么很可能接下来a+2,a+3也会被访问,这时候就分配stream用于预取接下来的地址。
3. 如果在historybuffer中没找到对应的地址,那么说明发生miss的地址不是连续的,就把发生miss的地址放入history buffer用于以后的对比。
4. 这个history buffer就是上图中的unit-stride filter。
二,对于非一致的访存进行预取
章节一种讲的是对于访存地址完全连续的情形,有些访存不是完全连续的,有可能是跳跃式但步幅是固定的,比如a+5,a+10,a+15等等。对于此种进行预取的方法是,用有限状态机进行判断,例如下图7。除了多个有限状态机和在filter中多一些标志位,其他都一样,不再赘述。czone用来探测访存在某些地址区间内的热度
Stream buffer的缺点:只考虑cache miss情况,cache 命中的情况不进行预取。事实上cache 命中时也应该考虑预取,比如a地址命中cache,a+1也命中,很可能a+2也会命中。但是根据旧的stream buffer设计,cache命中情况不经过stream,也更不会进入filter。所以添加以下逻辑进行完善:
参考论文:
1. Palacharla,Subbarao, and Richard E. Kessler. “Evaluating Stream Buffers as a SecondaryCache Replacement.” ACM SIGARCH Computer Architecture News 22, no. 2(1994): 24–33.
2. Jouppi, Norman P.“Improving Direct-Mapped Cache Performance by the Addition of a SmallFully-Associative Cache and Prefetch Buffers.” In Computer Architecture,1990. Proceedings., 17th Annual International Symposium on, 364–73. IEEE,1990. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=134547.