-
Notifications
You must be signed in to change notification settings - Fork 3
timing source
该文档讲述新的 llvm-prof 的TimingSource(时间源) 模型的计算过程。 TimingSource负责提供机器特征的参数,包括读取处理等。llvm-prof的timing模式则负责 结合PredBlockCounters计算出最后的时间。
文件参考: src/inst-timing.c
, src/libtiming.c
, lib/InstTemplate.cpp
对于LmbenchTiming的输出,直接用lmbench里面的 lat_ops
和 ???
即可。
所以下面的都是我们自己实现的 IrinstTiming 的输出。
默认很简单,对于不同的LLVM IR进行测度,然后再输出时间即可。在 inst-timing.c
中使用了一个特殊的空声明(占位符)
int inst_template(const char* templ, ...);
在 lib/InstTemplate.cpp
中再根据使用的具体的模板的不同,生成IR指令,并填充
进去。因此我们在IR层面可以方便的控制生成什么样的IR指令。
文件参考: include/TimingSource.h
, lib/TimingSource.cpp
机器特征的数据储存使用一个double类型的数组来实现,并且用一个enum类来指定数组中 的每一个元素代表着何种含义。
例如: LmbenchTiming
和 IrinstTiming
是具体的两个实现类,继承自
TimingSource(提供数组数据)和_timing_source::T(提供enum定义)。前者有一个
params
成员。后者提供一个 get
方法。
class LmbenchTiming:
public TimingSource, public _timing_source::T<LmbenchInstGroups>
class IrinstTiming:
public TimingSource, public _timing_source::T<IrinstGroups>
一个标准的TimingSource约定提供但不限定的方法有:
classify :: 确定一条指令所映射到的enum类型 count :: 计算一条指令或一个基本块的时间
对于enum定义,不同的时间源没有具体的规定。从而保证了时间源的多样性。 LmbenchTiming 是使用的lmbench测试的数据,所以它的enum中是用的 数据长度 × 计算方法 来定义的。而 IrinstTiming 是用的LLVM的IR模型,所以它的定义即是LLVM 的IR指令的种类。
每种时间源不同的地方还在于提供各自不同的处理文件的方法。例如IrinstTiming的
load_irinst负责读取我们自定义的输出格式。默认会覆盖掉父类的
file_initializer
函数指针。从而实现 init_with_file
共有方法。
文件参考: src/passes.cpp
最后的总时间的计算是交给 ProfileTimingPrint::runOnModule
来实现的。包括应用
模型。由于时间源的可扩展设计没有抽取抽象方法,所以需要利用dyn_cast来转换到子类
,然后再去直接访问各种方法。