目录
要使用此工具,必须--tool=cachegrind
在Valgrind命令行上指定 。
Cachegrind模拟程序如何与机器的缓存层次结构和(可选)分支预测器进行交互。它模拟具有独立的第一级指令和数据高速缓存(I1和D1)的机器,由统一的二级缓存(L2)支持。这完全符合许多现代机器的配置。
然而,一些现代机器具有三或四级缓存。对于这些机器(在Cachegrind可以自动检测缓存配置的情况下)Cachegrind模拟一级和最后一级缓存。这个选择的原因是最后一级缓存对运行时的影响最大,因为它掩盖了对主内存的访问。此外,L1高速缓存通常具有低关联性,因此模拟它们可以检测代码与该高速缓存交互不良的情况(例如,以行长为2的行列列逐列)。
因此,Cachegrind总是引用I1,D1和LL(最后一级)缓存。
Cachegrind收集以下统计信息(括号中给出每个统计量使用的缩写):
-
我缓存读取(
Ir
等于执行的指令数),I1缓存读取未命中(I1mr
)和LL缓存指令读取misses(ILmr
)。 -
D缓存读取(
Dr
等于内存读取次数),D1缓存读取未命中(D1mr
)和LL缓存数据读取misses(DLmr
)。 -
D缓存写入(
Dw
等于存储器写入数),D1缓存写入未命中(D1mw
)和LL缓存数据写入未命中(DLmw
)。 -
条件分支执行(
Bc
)和条件分支mispredicted(Bcm
)。 -
间接分支执行(
Bi
)和间接分支错误(Bim
)。
请注意,D1总访问由D1mr
+ 给出 D1mw
,LL总访问由ILmr
+ DLmr
+ 给出DLmw
。
为整个程序和程序中的每个功能提供这些统计信息。您还可以使用直接导致的计数来注释程序中的每一行源代码。
在现代机器上,L1故障通常会花费大约10个周期,LL错误可能花费多达200个周期,并且在10到30个周期的区域中,错误的分支成本。详细的缓存和分支分析可以非常有助于了解您的程序如何与机器交互,从而如何使其更快。
另外,由于每个执行指令都执行了一条指令高速缓存读取,您可以找出每行执行的指令数,这对于传统的分析来说是有用的。
首先,对于正常的Valgrind使用,您可能希望使用调试信息(-g
选项)编译 。但是与正常的Valgrind使用相比,您可能想要优化,因为您应该对程序进行配置,因为它将正常运行。
然后,您需要运行Cachegrind本身来收集分析信息,然后运行cg_annotate来获取该信息的详细介绍。作为可选的中间步骤,您可以使用cg_merge将多个Cachegrind运行的输出合并到一个文件中,然后将其用作cg_annotate的输入。或者,您可以使用cg_diff将两个Cachegrind运行的输出区分为一个文件,然后将其用作cg_annotate的输入。