0

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

我想计算使用(读取或写入)全局变量的次数,以便将其放置在最合适的内存类型中。
例如,以快速存取存储器类型存储常用变量。

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

有没有办法在不插入计数器或添加额外代码的情况下计算变量的使用次数?例如,使用汇编代码?

代码是用 C 编写的。

在我的手中:

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

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

非常感谢,

4

3 回答 3

0

我认为,您需要的是自动检测和/或分析。GCC 实际上可以为您进行配置文件引导的优化。与其他类型的检测一样,文档甚至提到了一个用于实现您自己的自定义检测的钩子。

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

此外,在虚拟机内执行可以(至少在理论上)做你所追求的。valgrind想到了。我认为,valgrind 实际上知道所有内存访问。我会寻找获取此信息的方法(然后将其与地图文件相关联)。

我不知道上述任何工具是否能完全解决您的问题,但您绝对可以使用 perf(如果它适用于您的平台)来查看在哪些代码领域花费了大量时间。然后可能有很多昂贵的内存访问,或者只是密集的计算,你可以通过盯着代码来判断是哪种情况。

请注意,编译器已经将经常访问的变量分配给寄存器,因此您所追求的信息类型不会为您提供准确的画面。即,虽然某些变量可能会被大量访问,但如果它的值大部分时间已经存在于寄存器中,那么缓存分配它可能不会改善很多。

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

于 2019-06-21T11:25:23.923 回答
0

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

为表达式设置观察点。当程序写入表达式 expr 并且其值发生变化时,GDB 将中断。此命令最简单(也是最流行)的用法是查看单个变量的值:

(gdb) 看 foo

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

设置当 expr 被程序读取或写入时将中断的观察点。

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

您可以为任何断点(或观察点或捕捉点)提供一系列命令,以便在程序因该断点而停止时执行……例如,以下是如何使用断点命令在入口处打印 x 的值到 foo 时,只要 x 是积极的。

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

该命令通常应该增加一个变量或将“读/写”打印到文件中,但您也可以添加其他内容,例如回溯。不确定使用 gdb 进行外部通信的最佳方式。也许以交互模式运行它就足够了。

于 2019-06-21T10:52:19.787 回答
0

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

于 2019-06-21T09:26:26.250 回答