为什么使用指针(低优化)会使程序更快?

问题描述 投票:1回答:2

我正在学习嵌入式C编程的教程,然后意识到使用指向变量的指针,然后用它来取消引用会使程序更快!

我对汇编有一个基本的了解,但是我没有想到为什么将变量的地址分配给指针它会更快,我们不是在谈论通过引用或通过指针或值传递!

我可以跟随,

  • 没有指针的代码:已经分配了内存地址来注册R0,就像使用指针在代码中发生的那样。
  • p_int成为注册表R0的别名,这有助于使程序更快?

不使用指针的代码:

int counter = 0;
int main() {
    while (counter < 6) {
        ++(counter);
    }
    return 0;
}

然后组装就像在enter image description here

相反,这是带有指针的代码:

int counter = 0;
int main() {
    int *p;
    p = &counter;
    while (*p < 6) {
        ++(*p);
    }
    return 0;
}

然后组装就像在enter image description here


更新

我和课程创建者联系了,他很乐意为我重播和分解,为了帮助其他可能遇到同样问题的人,我会留下问题和答案

要访问内存中的变量,CPU需要在其中一个寄存器中使用此变量的地址。在代码优化的最低级别,编译器在每次访问变量之前从代码存储器加载此地址。指针加速了这一点,因为main()函数中的局部变量被分配给寄存器。这意味着地址位于寄存器(在这种情况下为R0),并且不需要每次都加载并重新加载到寄存器中。在更高的优化级别,编译器生成更敏感的代码,没有指针的代码与指针一样快。 --MMS

c assembly arm embedded iar
2个回答
3
投票

一般来说:没有理由使用指针使程序运行得更快。在没有启用所有优化的情况下讨论程序的性能,就像课程创建者在您的引用中所做的那样,没有意义。这肯定不是改变编写代码方式的理由。

另一个旧的,经常使用但过时的技巧是将这样的循环写为向下计数而不是向上计数,因为与零的比较通常比对比值更快。但这也是您不应该影响编写代码的方式,因为现代编译器可以为您进行优化。

程序员应该做什么,以及人们编写课程应该教授的内容,就是尽可能简单地编写代码。这意味着你的例子都很糟糕,因为它们不必要地模糊不清,以及“预成熟优化”的例子。更好的代码是:

  int counter;
  ...
  for(counter=0; counter < 6; counter++)
  {}

这和代码一样可读,并且没有理由相信上述内容会比任何已知系统上的示例更糟糕。

做这个:

  • 尽可能编写最易读的代码。
  • 在发布中,启用优化。
  • 如果存在性能问题,基准测试并找到瓶颈。
  • 如果需要,手动优化瓶颈。可能考虑到特定的系统。

1
投票

编译器在优化级别之间变化的任何行为都是特定于实现的。因此,尽管你已经被展示出一些可能与演示相反的反直觉,但你不应该被告知这是一种因果关系。

以不同的方式编写代码总是可以触发性能改进或回归,而不同的优化级别有时会导致错误的更改。这应该是显而易见的,但是任何更高优化级别导致性能更差的情况(不是本示例的情况)都应该被视为编译器的问题。


0
投票

原始更新提供了一个很好的答案。此外,在原始版本中,“counter”是一个全局变量,因此ARM芯片上的每次访问都需要首先将变量加载到寄存器中。根据变量所在的位置和优化级别,这至少是一条LDR指令(可能更多),然后更新计数器++需要add指令和写回全局变量。

IF计数器被声明为局部变量,实际上,使用指针版本将不太理想。在这种情况下,大多数编译器会将计数器分配到寄存器中,然后访问它会非常快。如果使用指针,则强制计数器被分配给堆栈(因为其地址被分配给“p”),并且需要更多指令来进行添加和访问。


-2
投票

它恰好相反(几乎相同但只有一条指令:):

https://godbolt.org/z/xDYecQ

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.