Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any real life example of optimization benefit in case of passing const parameter by value ?

Here is the case,

I've tried to investigate a little bit advantages/disadvantages of implementation functions as follows :

void foo(const int a, const int b)
{
    ...
}

with common function prototype which is used as API and it's included in header file as shown below :

void foo(int a, int b)

I've found quite a huge discussion about this topic in the following question:

Similar Q

I agree there with answer from the rlerallut who is saying about self-documenting code and about being a little bit paranoid on the angle of security of your code.

However and this is the question, someone wrote there that using const for the usual parameters passed to the function can bring some optimization benefits. My question is does anybody have real life example which proves this claim ?

like image 886
Lazureus Avatar asked Nov 02 '22 05:11

Lazureus


1 Answers

"it might help the compiler optimize things a bit (though it's a long shot)."

I cant see how it would make a difference. It is most useful in this case to generate compiler warnings/errors when you try to modify the const variable...

If you were to try to invent an experiment to compare a function parameter declared as const or not for the purpose of optimization, pass by value. That means that this experiment would not modify the variable(s) because when const is used you would expect a warning/error. An optimizer that might be able to care, would already know that the variable is not modified in the code with or without the declaration and can then act accordingly. How would that declaration matter? If I found such a thing I would file the difference as a bug to the compiler bugboard.

For example here is a missed opportunity I found when playing with const vs not.

Note const or not doesnt matter...

void fun0x ( int a, int b);
void fun1x ( const int a, const int b);
int fun0 ( int a, int b )
{
    fun0x(a,b);
    return(a+b);
}
int fun1 ( const int a, const int b )
{
    fun1x(a,b);
    return(a+b);
}

gcc produced with a -O2 and -O3 (and -O1?)

00000000 <fun0>:
   0:   e92d4038    push    {r3, r4, r5, lr}
   4:   e1a05000    mov r5, r0
   8:   e1a04001    mov r4, r1
   c:   ebfffffe    bl  0 <fun0x>
  10:   e0850004    add r0, r5, r4
  14:   e8bd4038    pop {r3, r4, r5, lr}
  18:   e12fff1e    bx  lr

0000001c <fun1>:
  1c:   e92d4038    push    {r3, r4, r5, lr}
  20:   e1a05000    mov r5, r0
  24:   e1a04001    mov r4, r1
  28:   ebfffffe    bl  0 <fun1x>
  2c:   e0850004    add r0, r5, r4
  30:   e8bd4038    pop {r3, r4, r5, lr}
  34:   e12fff1e    bx  lr

Where this would have worked with less cycles...

push {r4,lr}
add r4,r0,r1
bl fun1x
mov r0,r4
pop {r4,lr}
bx lr

clang/llvm did the same thing the add after the function call burning extra stack locations.

Googling showed mostly discussions about const by reference rather than const by value and then the nuances of C and C++ as to what will or wont or can or cant change with the const declaration, etc.

If you use the const on a global variable then it can leave that item in .text and not have it in .data (and for your STM32 microcontroller not have to copy it from flash to ram). But that doesnt fit into your rules. the optimizer may not care and may not actually reach out to that variables home it might know to encode it directly into the instruction as an immediate based on the instruction set, etc...All things held equal though a non-const would have that same benefit if not declared volatile...

Following your rules the const saves on some human error, if you try to put that const variable on the left side of an equals sign the compiler will let you know.

I would consider it a violation of your rules, but if inside the function where it was pass by value you then did some pass by reference things and played the pass by reference const vs not optimization game....

like image 180
old_timer Avatar answered Dec 03 '22 13:12

old_timer