github
Pythia formulates hardware prefetching as a reinforcement learning task. For every demand request, Pythia observes multiple different types of program context information to take a prefetch decision. For every prefetch decision, Pythia receives a numerical reward that evaluates prefetch quality under the current memory bandwidth utilization. Pythia uses this reward to reinforce the correlation between program context information and prefetch decision to generate highly accurate, timely, and system-aware prefetch requests in the future.
构建预取器
cd $PYTHIA_HOME # ./build_champsim.sh <l1_pref> <l2_pref> <llc_pref> <ncores> ./build_champsim.sh multi multi no 1
source setvars.sh
目录:scripts
、traces
、experiments
工具:intel pinplay
构造实验: scripts/create_jobfile.pl
开始实验: jobfile.sh
The top-level files for Pythia are
prefetchers/scooby.cc
andinc/scooby.h
. These two files declare and define the high-level functions for Pythia (e.g., invoke_prefetcher, register_fill, etc.).
The released version of Pythia has two types of RL engine defined: basic and featurewise. They differ only in terms of the QVStore organization (please refer to our paper to know more about QVStore). The QVStore for basic version is simply defined as a two-dimensional table, whereas the featurewise version defines it as a hierarchichal organization of multiple small tables. The implementation of respective engines can be found insrc/
andinc/
directories.
inc/feature_knowledge.h
andsrc/feature_knowldege.cc
define how to compute each program feature from the raw attributes of a deamand request. If you want to define your own feature, extend the enum FeatureType in inc/feature_knowledge.h and define its corresponding process function.
inc/util.h
andsrc/util.cc
contain all hashing functions used in our evaluation. Play around with them, as a better hash function can also provide performance benefits.
过去研究不足
方案
将预取器作为强化学习代理。对于每个请求,Pytia都会观察多种不同类型的程序上下文信息,以做出预取决策。对于每个预取决策,Pythia都会收到一个数字奖励,该奖励将评估当前内存带宽使用情况下的预取质量。Pytia利用这种奖励来加强程序上下文信息和预取决策之间的相关性,以便在未来生成高度准确、及时且系统感知的预取请求。
目标:不同程序上下文信息 + 系统反馈 + 配置
Our goal in this work is to design a single prefetching frame-work that (1) can holistically learn to prefetch using both multiple different types of program features and system-level feedback information that is inherent to the design, and (2) can be easily customized in silicon via simple configuration registers to exploit different types of program features and/or to change the objective of the prefetcher (e.g., increasing/decreasing coverage, accuracy, ortimeliness) without any changes to the underlying hardware.
预取根据:program counter (PC), cacheline address (Address), page offset of a cacheline (Offset), or a simple combination of such features using simple operations like concatenation (+)
PC + Address, PC + Offset
强化学习
将Pythia定义为一个RL-agent,它通过与处理器和内存子系统交互来自主学习预取。对于每一个新的需求请求,Pythia都会提取一组程序特性。它将特征集作为状态信息,根据之前的经验进行预取操作。对于每一个预取动作(包括不预取),在给定各种系统级反馈信息的情况下,Pythia都会收到一个数值奖励,评估预取动作的准确性和及时性。
首先,使用RL框架,Pythia可以整体地学习使用其设计固有的多个程序特性和系统级反馈信息进行预取。其次,通过简单的配置寄存器,可以很容易地在硅中定制Pythia,以利用不同类型的程序特性和/或改变预取器的目标。这给了Pythia一个独特的好处,可以为各种工作负载和更改系统配置提供更高的性能改进,而不需要对底层硬件进行任何更改。
cache分成多个组set,每个组分成多个行way,linesize是cache的基本单位,从主存向cache迁移数据都是按照linesize为单位替换的。比如linesize为32Byte,那么迁移必须一次迁移32Byte到cache。 这个linesize比较容易理解,想想我们前面书的例子,我们从书架往书桌搬书必须以书为单位,肯定不能把书撕了以页为单位。书就是linesize。当然了现实生活中每本书页数不同,但是同个cache的linesize总是相同的。
所谓8路组相连( 8-way set associative)的含义是指,每个组里面有8个行。
描述一个cache需要以下参数 :
1、cache分级,L1 cache, L2 cache, L3 cache,级别越低,离cpu越近
2、cache的容量
3 、cache的linesize
4 、cache 每组的行个数
Cache基础知识
根据程序上下文信息推测数据访问模式,在访问之前进行预取
程序上下文信息:PC、Cache line address、Page Offset 以及之间的组合如:PC+offset
预取评估
一个理想的预取机制应该是高覆盖率,最大程度消除缓存缺失;高准确率,不会增加过多的存储带宽消耗;及时性,完全隐藏缓存缺失时延。我们可以看出来,这三个指标在某种程度上是对立的。如果采取激进的预取,可以提高覆盖率,但是准确率就会下降;如果采取保守的预取,只对准确预测的数据进行预期,可以提高准确率,但是覆盖率会降低。对于及时性,如果预取启动过早,可能在处理器使用该数据前就被替换出缓存或者预取缓冲区,“污染”了高速缓存;如果启动过晚,可能就无法完全隐藏缓存缺失时延。
分类
硬件预取分类
步长预取(stride prefetching)检测并预取连续访问之间相隔s个缓存数据块的数据,其中s即是步长的大小。硬件实现需要使用访问预测表,记录访问的地址,步长以及访存指令的pc值。流预取(stream prefetching)对流访问特征进行预取,流访问特征是指一段时间内程序访问的cache行地址呈现的规律,这种访问规律在科学计算和工程应用中广泛存在。硬件实现时,需要使用流识别缓冲记录一段时间内访存的cache行地址。预取引擎识别到流访问则进行预取。关联预取(association based prefetching)利用访存地址之间存在的关联性进行预取。
启用时机
预取可以在不同的地方启用并将预取数据放置到目的地址。预取可以在L1/L2/L3高速缓存,内存控制器,甚至是存储芯片中预加载DRAM行缓存时被启用。预取的数据通常被保存在启用预取的那一层,比如启用预取的高速缓存,或者在一个独立的预取缓冲区,从而避免预取数据“污染”缓存。
多核预取
在多核处理器设计中,预取设计尤为困难。如果预取过早,那么在一个处理器在访问某数据块之前,可能会因为另一个处理器对该数据块的访问导致数据块无效。同时,被预取的数据块可能替换了更有用的数据块。即使加大高速缓存的容量也不能像单处理器那样解决这些问题。过早的预取会导致某处理器从其它处理器中“窃取”缓存块,而这些缓存块很可能又被其它处理器再“窃取”回去。极端情况下,不合适的预取会给多处理器设计带来灾难,缓存缺失更加严重,进而大大降低性能。
预取需要考虑的点
指令预取 and 数据预取
ITLB,DTLB,L1I,L1D来分别服务指令和数据的访问。指令访问内存的模式比较好琢磨,毕竟只有读取没有写入,读取也比较规规矩矩,无法就顺序执行,不开心了就条件判断一下,跳转一下,所以目前CPU的指令预取策略都做得比较成熟,正确率甚至达到了大于99%的水平。相对来说,数据预取就难以摸透了很多,更少规律性地读写操作,当然也意味着对预测策略设计者来说更具有挑战性。
指令预取
需要考虑分支与循环
数据预取
可以将数据预取简单分为四类:
具体预取器
https://zhuanlan.zhihu.com/p/491673969