【问题标题】:avr if statement optimization for speed or sizeavr if 语句优化速度或大小
【发布时间】:2013-09-16 10:14:55
【问题描述】:

大家好!

我的 AVR 在我的 DIY 洒水器和鱼缸自动化方面取得了不错的进展,但我遇到了一个问题,这让我很烦恼。

哪个 if 语句在 AVR 上运行得更快?(在更少的时钟周期内) 多少?

if(temp_sensor[0] < -20)
{
    OCR1A--;
}
else if(tempout > tempset)
{
    OCR1A--;
}

或者

if((temp_sensor[0] < -20) || (tempout > tempset))
{
    OCR1A--;
}

再想一想,我的第二个问题是: 哪个占用空间少?

我的结论: 首先感谢大家的回答和cmets!

主要目标应该是编写简洁易懂的代码。

【问题讨论】:

  • 我猜你的意思是||在第二个。并且在-20之后也丢失了)。
  • 不要尝试过度优化。编写干净易读的 C 代码,让编译器为您进行优化。它会比你做得更好。如果你真的需要超级优化的代码,那就用 ASM 写吧。这是管理代码时钟周期消耗的唯一方法。
  • 我怀疑你是否受到 CPU 的任何限制,当我猜你使用 ADC 或 OneWire 连接的温度传感器需要数千个周期才能读取时,为什么还要担心 if 语句。跨度>

标签: c optimization if-statement avr


【解决方案1】:

您可以尝试一种(看似)无跳跃的方法:

const int8_t delta = temp_sensor < -20 || tempout > tempset;
OCR1A -= delta;

这有时可以提供更短的代码。当然它非常依赖 CPU,不确定 AVR 是否喜欢这样的代码。它也很可能会为 || 运算符的短路产生一个跳跃。编译器也完全有可能自行优化自己的跳跃。

【讨论】:

  • +1 用于提及 CPU 依赖性。例如,在 AVR 上,您没有 ARM 中的“条件执行”机制。因此,在这种情况下,您很可能会得到测试、分支(如果已完成)、测试分支(如果未完成)或类似的结果。这很可能是编译器为我在这个问题上看到的任何提议所产生的。所以我会坚持@LtWorf 的观点:为可维护性而编写。将循环摆弄留给编译器。如果 cylce 摆弄很重要,请自己编写程序集。
【解决方案2】:

这边

if((temp_sensor[0] < -20) || (tempout > tempset))
{
    OCR1A--;
}

是编写此类条件的更好方法。这更容易理解。至于它是否需要更少的滴答声,这并不重要,除非你做了几十万次,在这种情况下,只需检查它们,看看哪个更好

【讨论】:

    【解决方案3】:

    编写代码是为了可读性,而不是速度。尤其是在那些非常琐碎的情况下,编译器可以很容易地找出正在发生的事情并对其进行优化。

    你应该避免第一种方式,因为你有一些重复的代码,这并不理想。

    另外我必须指出,除非经过优化,否则 ||或 && 被编译为与 if 语句相同的分支指令,因此它们确实提高了代码的可读性,但并没有真正带来任何性能优势。

    【讨论】:

      【解决方案4】:

      添加到unwind,也可以这样使用:

      OCR1A -= (uint8_t)((temp_sensor < -20) | (tempout > tempset));
      

      | 是按位或。

      这将删除逻辑或 (||) 所需的 JUMP 代码。

      【讨论】:

        猜你喜欢
        • 2013-06-24
        • 1970-01-01
        • 2020-11-23
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        相关资源
        最近更新 更多