Search code examples
cassemblyarmembeddediar

Why using pointers (with low optimization) makes the program faster?


I was following a tutorial on embedded C programming, then realized that using a pointer to point to variable, then using it to dereference makes the program faster!

I've a basic knowledge of assembly, but I didn't figure why assigning the address of a variable to pointer would it make faster, we are not talking about pass by reference or by pointer or by value!

As I can follow,

  • code without pointer: the memory address has been assigned to register R0, like exactly what happened in the code with the pointer.
  • the p_int became an alias to the register R0, how this can help making the program faster?

the code without using a pointer:

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

then the assembly would be like in enter image description here

Conversely, here is the code with a pointer:

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

then the assembly would be like in enter image description here


Update

I reached out with the course creator and he was kind to replay and break it down for me, for the sake of help for others who may have encountered the same problem, I'll leave the question and the Answer

To access a variable in memory, the CPU needs the address of this variable in one of the registers. At the lowest levels of code optimization, the compiler loads this address from the code memory before each and every access to the variable. The pointer speeds this up, because being a local variable inside the main() function is allocated to a register. This means that the address sits in a register (R0 in this case) and does not need to be loaded and re-loaded into a register each time. At higher levels of optimization the compiler generates a more sensible code and the code without the pointer is as fast as with the pointer. --MMS


Solution

  • In general: there is no reason why using pointers would make the program run faster. Discussing performance of programs without all optimizations enabled, like the course creator did in your quote, is not meaningful. It is certainly not a reason to change the way you write code.

    Another old, often used but obsolete trick, is to write such loops as down-counting instead of up-counting, since compares against zero are often faster than compares against values. But this is also something you should not let affect the way you write code, because a modern compiler can do that optimization for you.

    What programmers should do, and what people writing courses should teach, is to write the code as plain and readable as possible. Meaning that both your examples are bad, since they are needlessly obscure and examples of "pre-mature optimization". Better code would be:

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

    This is about as readable as code gets and there is no reason to believe that the above would perform worse than your examples on any known system.

    Do this:

    • Write the most readable code you can.
    • In release, enable optimizations.
    • If there are performance problems, benchmark and find bottlenecks.
    • Manually optimize the bottlenecks if needed. Possibly with a specific system in mind.