分析例程的缓存缺失

Profiling cache misses of a routine

本文关键字:缓存 例程      更新时间:2023-10-16

我想分析一个c++程序中特定例程的缓存未命中率。我知道一些分析工具,但它们似乎不太让我满意。

据我所知:

gprof可以生成调用图和代码覆盖,但它不包括缓存缺失分析。

valgrind (cachegrind)可以配置缓存缺失,但似乎只针对整个应用程序。

oprofile确实有一个基于符号的输出。但是我有点困惑:如果过程a()调用B()(可能是库或系统调用),并且缓存丢失发生在B()内部,它归因于a()吗?毕竟,我想计算A()在整个执行过程中的缓存丢失次数。

最后一个问题。OProfile需要为每个新会话重新启动守护进程。假设我想通过多次运行来分析我的程序——使用一组不同的参数和输入。我怎样才能用自动化的方式来做呢?是否有像在代码中插入gettimeofday()这样的方法来获取缓存统计信息?

假设您在特定函数中的缓存缺失是重要的,那么使用cachegrind或oprofile应该可以很好地工作。如果该函数中的缓存丢失对于程序的整个执行来说并不重要,那么为什么要为此烦恼呢?

从记忆中,但它是几年以来,我使用的oprofile,但你不需要重新启动守护进程,只是使用"重置我的数据"(opcontrol --reset)。由于oprofile是系统范围的,您可以简单地运行一个脚本,其中包含多个测试用例—oprofile将为每个进程拆分数据,但是如果您在任何特定函数中有高缓存使用率,则应该显示在缓存未命中列表中。如果它没有出现,那么你的代码并没有在缓存中丢失。

我一直在做的是写一个脚本,做opcontrol --reset --start event=CPU_CLK_UNHALTED:400000,然后是任何程序我正在测试,然后是opcontrol --stop --save=oprofile.result

请注意,oprofile是基于统计和样本的,因此您不能测量单个缓存缺失,它记录缓存缺失计数器达到极限的地址。所以你可能会遇到这样一种情况,如果你有1000次缓存失败的"限制",那么函数a就会有999次缓存失败,然后函数B只有一次缓存失败,函数B就会被"记为"缓存失败。然而,假设您没有极度病态的代码,您将在缓存中丢失的代码区域中获得缓存缺失记录。