Green Hills的编译优化等级到底要怎么调,还有优化以后变量没有办法被观察到,这要怎么处理,这些问题一般是出现在从Debug版本往性能版本那边切过去的阶段。编译优化会去把函数给内联展开,把没有用到的代码给删掉,重新去分配寄存器,对指令的先后顺序也做一些调整,程序的运行结果虽然没有变,但这可不表示它生成出来的机器代码,跟每一行的源代码还能一一对应得上。Green Hills编译器里面,性能的级别和调试的级别都是可以选的,MULTI调试器则可以把源代码、内存、寄存器,还有函数调用栈放到一起,去查看程序的状态。
一、Green Hills编译优化等级怎么调整
人们最好不要在整个工程里面,把优化等级反反复复地改来改去,一种比较稳当的做法,是先把两个配置给分开,一个叫Debug配置,一个叫Release配置,在调试阶段,让调试信息保留得比较完整,等到后面要去对性能进行验证的时候,再把优化强度给提上去。
1、进入工程构建选项
进到MULTI的Project Manager里面去,把工程,或者是构建目标,或者是要单独设一下的源文件给选上,然后再去把对应的【Build Options】或者【Compiler Options】给打开。
MULTI的版本不一样,目标处理器不一样的话,选项被显示出来的名字可能也会有点差别,人们可以重点去里面找一找跟【Optimization】、【Performance】,还有【Debugging】有关的设置,在调整之前,要先弄明白这次改动是会作用到整个工程上,还是只对下面的一个子工程,还是就单个的源文件,这样才能避免只是改掉了一部分模块。
2、按构建用途选择等级
在调试版本里面,可以先让优化关掉,或者是用一个偏向调试的低级别优化,这样子断点的位置、单步执行,还有局部变量的情况,就能更靠近源代码的样子,等到要去测执行效率、ROM占用,还有最后要交付出去的版本时,再把优化切换成面向速度的,或者是面向代码尺寸的,又或者是强度更高的全局优化。
Green Hills编译器里面,是包含了很多种面向执行速度和代码尺寸的优化能力的,优化强度一旦被提高上去,编译器就会更加积极地去把代码重新组织一下。
3、修改后执行完整重编译
把【Optimization】调过以后,人们应当把旧的目标文件给清理掉,再重新去构建一遍,不能只是去链接现在已经有的那些对象文件。
要是有一些.o文件,还是用之前的参数生成出来的,最后出来的程序里面,就可能把不同优化等级的东西给混在了一起,到了这个时候,调试的表现、代码尺寸,还有性能的测试,就都会变得让人很难解释得清楚,要是工程里面还用了自动生成代码或者静态库的话,也得去确认一下这些模块有没有跟着一起重新编译过。
二、Green Hills优化后变量无法观察怎么办
在把优化给打开了以后,MULTI里面可能会出现变量用不了,数值跳来跳去,或者是单步的时候位置连不上的情况,这些不一定就表示调试器出了什么异常,这个变量,可能已经被编译器给拿掉了,被放到寄存器里面去了,或者干脆是用另一个表达式,把原来一串计算过程给直接替换掉了。
1、确认变量当前是否仍然有效
先要把断点给放到一个位置上,这个地方是变量已经被赋值完了,而且后面还有代码会去用到它的,放好以后,再通过【Watch】窗口,或者是局部变量窗口去瞧一瞧。
要是程序还没有跑到初始化那条语句那里,又或者已经跑出了变量还在起作用的范围,调试器自然就没办法把正常数值给显示出来了,优化以后,有些源代码的行,还有可能被合并到一块儿去了,断点停下来的位置,未必就正好是变量能有一个稳定存储位置的时刻。
2、检查调试信息和程序文件
要去确认一下,工程是不是把调试信息给生成出来了,还要去核对一下MULTI现在加载的可执行文件,跟刚刚才编译出来的版本,是不是同一个东西。
要是目标板上面跑着的是一个旧程序,但调试器那头加载的是新符号,变量的地址,还有源代码的行,自然也就对不上了,一旦优化等级被改过之后,函数的地址、局部变量待的位置,还有指令布局,这些东西都有可能会变,所以要把程序重新下载一次,并且重新去建一个调试会话。
3、降低局部模块的优化等级
要是人们只需要去观察某一个函数,或者某一个源文件里面的情况,那就可以单独地把这个模块的优化等级给降下来,用不着把整个工程都给改成没有优化的样子。
这样做,既能把其他模块接近Release版本的运行状态给保留下来,去检查关键变量的时候,也会方便一些,可不要为了让变量能显示出来,就随随便便地去加上volatile,这个限定符,会使得编译器对访问顺序和存储行为的处理发生改变,只有变量本身牵扯到硬件寄存器,或者是中断共享,又或者是别的什么有明确说法的地方,才适合按照设计要求去用它。
三、降低优化后仍然看不到变量怎么排查
变量观察不到,有时候并不光是优化等级一个原因造成的,它可能还跟任务的上下文、断点位置、函数被内联进去了,还有调试文件对不上这些东西有关,得接着把反汇编也结合到一块儿,再去确认。
1、查看反汇编和寄存器
去把【Disassembly】和【Register View】给打开,看一看变量所对应的计算,是不是已经变成对寄存器的操作了。
MULTI调试器是支持去查看内存、寄存器,还有调用栈的,靠着这些信息,就能帮着人们去判断,变量是被优化给删掉了,还是暂时被保存在了哪个寄存器里面。
2、确认当前任务和调用栈
在多任务,或者是多核的项目里面,要先去看一下,现在停下来的,到底是哪一个任务、哪一个线程,还有哪一个处理器核心,局部变量只是属于一个特定的调用栈的,当停在另外一个任务上面的时候,就算函数名称是一样,也可能看不到想要的数据。
3、比较Debug与Release行为
可以分别留一套Debug和Release的构建配置在那里,Debug版本,就用来去把逻辑和变量变化给定位出来,Release版本,则拿来对性能、时序,还有最后的运行状态去做验证,要是问题只出现在优化开得很高的版本上,那就还得去检查一下,代码里面是不是有没被初始化的变量,越界去访问了,或者是依赖了执行顺序这一类的隐患,不能简简单单地就把原因归到“调试器看不到”上面去。
总结
Green Hills编译优化等级怎么调整,还有优化后变量无法观察怎么办,这里面的重点,就是要把调试需要和性能需要给分开来处理,优化等级应该在工程构建选项里面去调,改过以后,把旧东西给清理掉,再完整地重新编译一次;变量观察不到的时候,要照着顺序,去检查作用域、断点位置、调试信息、程序版本,还有任务上下文,要是确实是被优化给影响到了,那就可以只把目标文件或者函数所在模块的优化等级给降下来,再结合着【Disassembly】、【Register View】,还有内存窗口,去把实际运行状态给确认好。
