Difference between revisions of "BoostC Optimizations"

From OpenCircuits
Jump to navigation Jump to search
 
(8 intermediate revisions by the same user not shown)
Line 6: Line 6:
  
  
== some notes from the forum still to be formatted ==
+
= some notes from the forum still to be formatted =
  
 
The following post yeilded several real and unreal optimizations  
 
The following post yeilded several real and unreal optimizations  
Line 12: Line 12:
  
  
==== Incrementing ====
+
== Incrementing ==
  
 
subtracting/deincrementing is faster than adding/incrementing
 
subtracting/deincrementing is faster than adding/incrementing
Line 18: Line 18:
 
Valid?  believed not to be true
 
Valid?  believed not to be true
  
==== Avoid Division ====
+
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
 +
 
 +
== Avoid Division ==
  
 
not using division saves ~35 bytes
 
not using division saves ~35 bytes
  
Valid?  division is slow, but we think not by poweres of 2, which are shifts ( if divisor know at compile time )
+
Valid?  division is slow, but we think not by powers of 2, which are shifts ( if divisor know at compile time )
  
==== Left vs Right Shift ====
+
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
 +
 
 +
== Left vs Right Shift ==
  
 
Left Shifting is faster than Right
 
Left Shifting is faster than Right
  
==== Function call in ISR =====
+
Valid?  believed not to be true.
 +
 
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
 +
 
 +
== Function call in ISR ==
  
 
Calling a function in an ISR takes longer than outside an ISR
 
Calling a function in an ISR takes longer than outside an ISR
 +
 
Valid?  believed not to be true
 
Valid?  believed not to be true
  
==== Function called Only Once =====
+
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
 +
 
 +
== Function called Only Once ==
  
-Never use a function for a single operation, you waste time calling and returning
+
Never use a function for a single operation, you waste time calling and returning
  
Valid?  believed not to be true
+
Valid?  believed not to be true.
 +
 
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
==== Shift for Division =====
+
== Shift for Division ==
  
 
Use bit shifting instead of division for speed savings and possible ram savings
 
Use bit shifting instead of division for speed savings and possible ram savings
Line 45: Line 58:
 
(shifting one bit right is equal to dividing by two, etc)
 
(shifting one bit right is equal to dividing by two, etc)
  
Valid?  believed not to be true, optimizer is smart enough to do this
+
Valid?  believed not to be true, optimizer is smart enough to do this.
  
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
==== Arrays and Pointers ====
+
== Arrays and Pointers ==
  
 
Both arrays and pointers generate a lot of code. Use plain variables instead where possible.
 
Both arrays and pointers generate a lot of code. Use plain variables instead where possible.
Line 77: Line 91:
 
something similar happens when you are working with struct variables.
 
something similar happens when you are working with struct variables.
  
 +
Valid? We are pretty sure it is.
  
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
 +
== ROM vs RAM ==
  
==== ROM vs RAM ====
+
Write constants into ROM not RAM  
-Write constants into ROM not RAM  
 
  
 
Valid?  In that you save RAM at the expense of ROM, normally you have more ROM than RAM.
 
Valid?  In that you save RAM at the expense of ROM, normally you have more ROM than RAM.
  
==== Return Values ====
+
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
 +
 
 +
== Return Values ==
  
 
Do not return values from functions that you wont use/do not need.
 
Do not return values from functions that you wont use/do not need.
Line 91: Line 109:
 
Valid?  We think so, seems like it must be.
 
Valid?  We think so, seems like it must be.
  
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
==== ROM vs RAM ====
+
== ROM vs RAM ==
  
 
+
Reuse common code or write a common function and call it will save huge amounts of space
-Reuse common code or write a common function and call it will save huge amounts of space
 
 
( i suspect agressive opt in BoostC may negate this last but i've yet to test)
 
( i suspect agressive opt in BoostC may negate this last but i've yet to test)
  
Valid?  We think so, but even if not it good coding pratice.
+
Valid?  We think so, but even if not, it good coding pratice.
  
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
 +
== ()?:; ==
  
 
i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields  
 
i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields  
Line 110: Line 130:
 
left empty or there is no value in using it and will actually result in longer code.
 
left empty or there is no value in using it and will actually result in longer code.
  
CODE
+
 
(test)?(result=1):(result=0);
+
    (test)?(result=1):(result=0);
  
 
VS
 
VS
CODE
 
if(test)
 
{
 
  result=1;
 
}
 
else
 
{
 
  result=0;
 
}
 
  
 +
    if(test)
 +
    {
 +
          result=1;
 +
    }
 +
    else
 +
    {
 +
          result=0;
 +
    }
  
  
i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields slightly smaller/faster code...
 
  
I tried that one out and there's no gain on SourceBoost C (for PIC16) on any optimization level.
 
 
For code like that, I would expect this:
 
CODE
 
result = (test ? 1 : 0)
 
to do better, but it doesn't, either...
 
 
 
 
 
 
QUOTE (edt @ Dec 29 2006, 01:23 PM)
 
QUOTE (emte @ Dec 27 2006, 05:07 PM)
 
 
i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields slightly smaller/faster code...
 
i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields slightly smaller/faster code...
  
Line 145: Line 151:
  
 
For code like that, I would expect this:
 
For code like that, I would expect this:
CODE
 
result = (test ? 1 : 0)
 
to do better, but it doesn't, either...
 
  
 +
    result = (test ? 1 : 0)
  
 
+
to do better, but it doesn't, either...
 
 
 
 
Odd, altho my tests were simply:
 
 
 
CODE
 
    (testBit)?(_ONE = 1):(_ONE = 0);
 
0039  08A1      MOVF main_1_testBit, F
 
003A  1903      BTFSC STATUS,Z
 
003B  283E      GOTO    label268438744
 
003C  1486      BSF gbl__ONE,1
 
003D  283F      GOTO    label268438746
 
003E        label268438744
 
003E  1086      BCF gbl__ONE,1
 
003F        label268438746
 
 
 
        if(testBit)
 
003F  08A1      MOVF main_1_testBit, F
 
0040  1903      BTFSC STATUS,Z
 
0041  2844      GOTO    label268438747
 
0044        label268438747
 
 
 
        {
 
            _ONE = 1;
 
0042  1486      BSF gbl__ONE,1
 
 
 
        }
 
        else
 
0043  2837      GOTO    label268438739
 
 
 
        {
 
            _ONE = 0;
 
0044  1086      BCF gbl__ONE,1
 
 
 
        }
 
  
  
Line 197: Line 167:
 
that with the new version, it did not even occur to me that it may have changed  
 
that with the new version, it did not even occur to me that it may have changed  
  
 +
 +
more in the post  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
 
----------------
 
----------------
 +
 +
 +
do not get this one
  
 
Hmm it looks like the if-else might actually be one line shorter now ... altho it is
 
Hmm it looks like the if-else might actually be one line shorter now ... altho it is
Line 219: Line 194:
 
... hmm maybe i should add that example to handy functions ...
 
... hmm maybe i should add that example to handy functions ...
  
 +
Post:  http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574
  
 +
= Still More we are working on =
  
==== Still More we are working on ====
+
== Soft vs Hard Stack ==
 
 
  
 
Software stack is slower than hardware ( but deeper )
 
Software stack is slower than hardware ( but deeper )
Line 228: Line 204:
 
Valid? we think so.
 
Valid? we think so.
  
Inline function does not really use call and return so is faster, but if called multiple time may take more space ( but for short funtions the call return... can take more space than the function itself.  Would be nice if someone did measurements.
+
== Inline Functoion ==
 +
 
 +
Inline function does not really use call and return so is faster, but if called multiple time may take more space ( but for short funtions the call return... can take more space than the function itself.  Would be nice if someone did measurements. [[BoostC Inline Functions]]
  
 
Valid? we think so.
 
Valid? we think so.
  
 +
== Local vs Global ==
  
 
Local values vs global variables.
 
Local values vs global variables.
 +
 +
Issue not understood, local may require some stack heap management, but space should be recovered when function exits so local variable saves memory overall.  Probably you should follow good pratices and use variables of th narrowest scope possible.
 +
 +
== Links ==
 +
 +
[http://user.it.uu.se/~jakob/publications/engblom-esc-sf-2001.pdf Getting the Least Out of Your C Compiler Class #508, Embedded Systems Conference San Francisco 2001]
 +
 +
[[Category:BoostC]][[Category:PIC]]

Latest revision as of 17:25, 3 August 2009




some notes from the forum still to be formatted[edit]

The following post yeilded several real and unreal optimizations http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574


Incrementing[edit]

subtracting/deincrementing is faster than adding/incrementing

Valid? believed not to be true

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Avoid Division[edit]

not using division saves ~35 bytes

Valid? division is slow, but we think not by powers of 2, which are shifts ( if divisor know at compile time )

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Left vs Right Shift[edit]

Left Shifting is faster than Right

Valid? believed not to be true.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Function call in ISR[edit]

Calling a function in an ISR takes longer than outside an ISR

Valid? believed not to be true

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Function called Only Once[edit]

Never use a function for a single operation, you waste time calling and returning

Valid? believed not to be true.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Shift for Division[edit]

Use bit shifting instead of division for speed savings and possible ram savings

(shifting one bit right is equal to dividing by two, etc)

Valid? believed not to be true, optimizer is smart enough to do this.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Arrays and Pointers[edit]

Both arrays and pointers generate a lot of code. Use plain variables instead where possible.

I just saved a lot of bytes by reducing the number of index access on array vars.

a stupid and useless example:

  char var[10];
  
  for( i= 0; i<10;i++){
     if ((var[i]==this) || (var[i]==that)) var[i]=somefunction(var[i]);
     var[i]+=2;
  }


if you need to have access on a particular index several times i'm using an extra dummy var.

  char var[10], dummy;
  
  for( i= 0; i<10;i++){
     dummy= var[i];
     if ((dummy==this) || (dummy==that)) dummy=somefunction(dummy)  {
        var[i]= dummy+=2;
     }
  }

something similar happens when you are working with struct variables.

Valid? We are pretty sure it is.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

ROM vs RAM[edit]

Write constants into ROM not RAM

Valid? In that you save RAM at the expense of ROM, normally you have more ROM than RAM.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Return Values[edit]

Do not return values from functions that you wont use/do not need.

Valid? We think so, seems like it must be.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

ROM vs RAM[edit]

Reuse common code or write a common function and call it will save huge amounts of space ( i suspect agressive opt in BoostC may negate this last but i've yet to test)

Valid? We think so, but even if not, it good coding pratice.

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

()?:;[edit]

i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields slightly smaller/faster code on every compiler i've ever used versus using if()else(); The gain varies from 1-3 lines of asm code, which, if in a high use test will amount to a conciderable savings.

The conditional aspect of this is that the fail function must do something it cannot be left empty or there is no value in using it and will actually result in longer code.


    (test)?(result=1):(result=0);

VS

    if(test)
    {
         result=1;
    }
    else
    {
         result=0;
    }


i had forgotten about this one but the good old ()?:; (tri-unary?) function conditionally yields slightly smaller/faster code...

I tried that one out and there's no gain on SourceBoost C (for PIC16) on any optimization level.

For code like that, I would expect this:

    result = (test ? 1 : 0)

to do better, but it doesn't, either...


with the asm disassembly, but it looks like i am wrong about the new version of the compiler. i am glad to see that these are now the same as they are identical chunks of code.

If i recall correctly, the reason they were different is that the if-else used to use two bit tests to determine logic, which is how you would do it if you had more ifelse tests.

Now i am back to using ?:; just for a cleaner look to code i guess. Thanks for testing that with the new version, it did not even occur to me that it may have changed


more in the post http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574



do not get this one

Hmm it looks like the if-else might actually be one line shorter now ... altho it is just a lable line.


result= test&1;


Yes that would possibly work in this case as it is an extremly simple example. But on the otherhand if you were writting code for an indicator light, say to notify of an AD conversion, you could not use the return value as your test bit. ie. if test = 4 that mask would fail but (test)?(result=1):(result=0); would work since all non-zero/positives would set result.

i find this handy if you have more than one AD module on your device instead of using the flags as you can now build an AD FIFO cyclical stack or non-blocking time sensitive functions. (all that slow eeprom write stuff while your doing another conversion) ... hmm maybe i should add that example to handy functions ...

Post: http://forum.sourceboost.com/index.php?showtopic=2433&pid=9574&mode=threaded&start=#entry9574

Still More we are working on[edit]

Soft vs Hard Stack[edit]

Software stack is slower than hardware ( but deeper )

Valid? we think so.

Inline Functoion[edit]

Inline function does not really use call and return so is faster, but if called multiple time may take more space ( but for short funtions the call return... can take more space than the function itself. Would be nice if someone did measurements. BoostC Inline Functions

Valid? we think so.

Local vs Global[edit]

Local values vs global variables.

Issue not understood, local may require some stack heap management, but space should be recovered when function exits so local variable saves memory overall. Probably you should follow good pratices and use variables of th narrowest scope possible.

Links[edit]

Getting the Least Out of Your C Compiler Class #508, Embedded Systems Conference San Francisco 2001