【问题标题】:AtmelStudio compiled code: How to optimize compilerAtmelStudio 编译代码:如何优化编译器
【发布时间】:2016-02-14 06:47:44
【问题描述】:

代码:

uint8_t count;

ISR(TIMER1_OVF_vect, ISR_NAKED)
{
    count++;
    reti();
}

生成的程序集是:

--- F:\atmel-prj\compiler-test2\compiler-test2\Debug/.././compiler-test2.c -----
{
00000048  PUSH R1       Push register on stack 
00000049  PUSH R0       Push register on stack 
0000004A  IN R0,0x3F        In from I/O location 
0000004B  PUSH R0       Push register on stack 
0000004C  CLR R1        Clear Register 
0000004D  PUSH R24      Push register on stack 
    count++;
0000004E  LDS R24,0x0100        Load direct from data space 
00000050  SUBI R24,0xFF     Subtract immediate 
00000051  STS 0x0100,R24        Store direct to data space 
}
00000053  POP R24       Pop register from stack 
00000054  POP R0        Pop register from stack 
00000055  OUT 0x3F,R0       Out to I/O location 
00000056  POP R0        Pop register from stack 
00000057  POP R1        Pop register from stack 
00000058  RETI      Interrupt return 

现在,在我看来,至少可以消除一个,最多两个 push-pop 对:

  1. 为了节省一个 push-pop,使用 r0 来消除 r24

    PUSH R1     Push register on stack 
    PUSH R0     Push register on stack 
    IN R0,0x3F      In from I/O location 
    PUSH R0     Push register on stack 
    CLR R1      Clear Register 
    count++;
    LDS R0,0x0100       Load direct from data space 
    SUBI R0,0xFF        Subtract immediate 
    STS 0x0100,R0       Store direct to data space 
    ...
    
  2. 看到没有代码将 r1 用于 0 值,因此仅将 r1 用于所有目的。

    PUSH R1     Push register on stack 
    IN R1,0x3F      In from I/O location 
    PUSH R1     Push register on stack 
    CLR R1      Clear Register 
    count++;
    LDS R0,0x0100       Load direct from data space 
    SUBI R0,0xFF        Subtract immediate 
    STS 0x0100,R0       Store direct to data space 
    ...
    

这些都可以为我们节省宝贵的字节和微秒。

有没有一种方法可以以某种方式将这些或类似的优化放入 atmel studio 工具链/库中,以便生成的编译代码稍微好一些?
很多关于中断和函数调用的代码,以及一些 C 到汇编的翻译都可以优化很多。

【问题讨论】:

  • 这适用于 atmel AVR 架构吗? gcc 可以针对 AVR。它是gcc.godbolt.org 上的可用目标之一。我不知道 Atmel 的编译器在优化其他代码方面有多好,也不知道它是否有启用优化的选项。
  • 我有 Atmel Studio 6,它似乎有一个 gcc 编译器。无论如何,谢谢你的建议,我会看看 gcc 的 avr 目标。
  • 您启用优化了吗?许多 IDE 默认使用某些配置文件进行调试,优化关闭。
  • 是的。这是与-O3。 -O1 也一样。还在调试选项关闭的情况下进行了测试。
  • 在回答 Peter 时,gcc.gnu.org/wiki/avr-gcc 上的 gcc 文档和 Atmel Studio 提供的文档都具有相同的文本。它们必须是相同的软件。无论哪种方式,我看到一些相当明显的优化没有完成。所以,要么我不太了解代码生成和优化,要么工具链中不存在一些明显的优化。我的问题主要是找出是否有可能以某种方式更改由编译器构造的序言和尾声,而无需将我自己的所有代码都翻译成程序集。

标签: c assembly compiler-construction atmega atmelstudio


【解决方案1】:

我还发现生成的汇编代码可以优化。那时我还没有使用-On 选项。 我发现被调用函数的代码(它在寄存器中接受参数);将其复制到堆栈中(以将干净的副本保留为“自动”C 变量...在大多数情况下是无用的)并且进一步将此值复制回原始寄存器!而这个寄存器之前只是读过,GCC 应该知道。

如果您将 Atmel Studio 与默认编译器(即 GCC)一起使用,则您的二进制代码优化取决于工具链行为(因此,在其命令行中指定的选项)。

为了获得最好的结果,您可以尝试直接使用 avr-gcc 编译您的源代码树(以设置 Atmel Studio 无法为您设置的选项)。

使用另一个工具链是获得(理论上)最好结果的另一种方法。 无论如何,我怀疑任何其他工具链都会比 GCC 提供(整体)更好的结果。

【讨论】:

  • 那时我可能还没有听说过clang!不确定 clang 是否有 AVR 后端...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多