如何统计一个全局变量被使用了多少次(读写)?

How to count how many times a global variable was used (read and write)?

我正在尝试优化 C 代码项目。

我想统计一个全局变量被使用(读取或写入)了多少次,以便将它放在最合适的内存类型中。
例如,将常用变量存储在快速存取内存类型。

出于确定性原因禁用数据缓存。

有没有一种方法可以在不插入计数器或添加额外代码的情况下计算一个变量被使用了多少次?例如,使用汇编代码?

代码是用C写的

我拥有:

A) (.map) 文件,由 GCC 编译器生成,我从中提取全局变量名称、地址和大小。

B) 使用GCC编译器-S标志生成的项目汇编代码。

非常感谢,

您可以使用 Visual Studio(或其他 IDE)执行此操作:搜索源代码中使用变量的所有位置,放置条件断点,记录一些信息,附加到进程,并启动使用该变量的功能。您可以计算输出中的实例 window.

GDB 有一个叫做 watchpoints 的东西:https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html

Set a watchpoint for an expression. GDB will break when the expression expr is written into by the program and its value changes. The simplest (and the most popular) use of this command is to watch the value of a single variable:

(gdb) watch foo

awatch [-l|-location] expr [thread thread-id] [mask maskvalue]

Set a watchpoint that will break when expr is either read from or written into by the program.

可以将命令附加到观察点:https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html#Break-Commands

You can give any breakpoint (or watchpoint or catchpoint) a series of commands to execute when your program stops due to that breakpoint… For example, here is how you could use breakpoint commands to print the value of x at entry to foo whenever x is positive.

break foo if x>0 
commands 
silent 
printf "x is %d\n",x 
cont 
end

该命令通常应递增一个变量或将 "read/write" 打印到一个文件,但您实际上也可以添加其他内容,例如回溯。不确定使用 gdb 进行对外通信的最佳方式。也许它足以让您 运行 在交互模式下使用它。

我认为,您需要的是自动检测 and/or 分析。 GCC 实际上可以为您做 profile-guided 优化。除了 other types of instrumentation,文档甚至还提到了用于实现您自己的自定义检测的挂钩。

有几种性能分析工具,例如 perfgprof 分析器。

此外,在虚拟机内执行可以(至少在理论上)完成您想要的。 valgrind 浮现在脑海中。我认为,valgrind 实际上知道所有内存访问。我会寻找获取此信息的方法(然后将其与地图文件相关联)。

我不知道上述任何工具是否能准确解决您的问题,但您绝对可以使用 perf(如果它适用于您的平台)查看代码的 区域 花费了大量时间。那么可能要么有很多昂贵的内存访问,要么只是密集的计算,你可以通过盯着代码找出这种情况。

请注意,编译器已将频繁访问的变量分配给寄存器,因此您所获取的信息不会为您提供准确的信息。 IE。虽然一些 变量 可能会被大量访问,但 cache-allocating 如果它的值大部分时间已经存在于寄存器中,它可能不会有太大改善。

还要考虑优化在汇编级别对程序的影响很大。因此,任何性能统计数据(例如内存访问计数器)在优化和不优化的情况下都会有所不同。您应该感兴趣的是优化案例。另一方面,如果可行的话,使用优化后的程序更难恢复关于哪个位置对应于哪个变量的信息。