我正在尝试优化一个C代码项目。
我想计算全局变量的使用次数(读取或写入),以便将其放置在最合适的内存类型中。
例如,以快速存取存储器类型存储常用变量。
出于确定性原因,数据缓存被禁用。
有没有办法在不插入计数器或添加额外代码的情况下计算变量的使用次数? 例如,使用汇编代码?
代码是用 C 语言编写的。
在我拥有:
A) (.map) 文件,由 GCC 编译器生成,我从中提取全局变量名称、地址和大小。
B) 使用 GCC 编译器 -S 标志生成的项目的汇编代码。
多谢
GDB有一个名为watchpoints的东西: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html
设置表达式的观察点。当表达式时,GDB 将中断 expr 由程序写入,其值会发生变化。这 此命令的最简单(也是最流行)的用法是观看 单个变量的值:
(GDB) 手表 foo
awatch [-l|-location] expr [thread thread-id] [mask maskvalue]
设置一个观察点,当读取或写入 expr 时,该观察点将中断 由程序进入。
命令可以附加到观察点:https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html#Break-Commands
您可以为任何断点(或观察点或捕获点)提供一系列命令,以便在程序因该断点而停止时执行...例如,下面介绍如何使用断点命令进行打印 当 x 为正时,x 在进入 foo 时的值。
break foo if x>0
commands
silent
printf "x is %dn",x
cont
end
该命令通常应该递增变量或打印"读/写"到文件,但您也可以添加其他内容,例如回溯。不确定使用 gdb 进行向外通信的最佳方式。也许它足以让您在交互模式下运行它。
您可以使用Visual Studio(或其他IDE)执行此操作:搜索源代码中使用变量的所有位置,放置条件断点,记录一些信息,附加到进程,然后启动使用该变量的功能。您可以在输出窗口中对实例进行计数。
我认为,您需要的是自动检测和/或分析。GCC 实际上可以为您进行按配置文件优化。除了其他类型的检测外,文档甚至还提到了一个用于实现您自己的自定义检测的钩子。
有几种性能分析工具,例如perf
和gprof
探查器。
此外,虚拟机内的执行可以(至少在理论上)完成您所追求的事情。valgrind
浮现在脑海中。我认为,valgrind实际上知道所有内存访问。我会寻找方法来获取这些信息(然后用地图文件进行核心化)。
我不知道上述任何工具是否完全解决了您的问题,但是您绝对可以使用perf(如果它可用于您的平台)来查看在哪些代码领域花费了大量时间。然后可能有很多昂贵的内存访问,或者只是密集的计算,你可以通过盯着代码来找出哪种情况。
请注意,编译器已经将频繁访问的变量分配给寄存器,因此您所追求的信息类型不会为您提供准确的图片。 也就是说,虽然某些变量可能会被大量访问,但如果它的值大部分时间已经存在于寄存器上,那么缓存分配它可能不会有太大改善。
还要考虑到优化在程序集级别对程序影响很大。因此,任何性能统计信息(如内存访问计数器)在优化和不优化的情况下都会有所不同。您应该感兴趣的是优化的案例。另一方面,如果可行的话,使用优化程序恢复有关哪个位置对应于哪个变量的信息会更难。