go_away

Author Topic: New Tutorial - code optimisation  (Read 2311 times)

0 Members and 1 Guest are viewing this topic.

Offline WebbotTopic starter

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
New Tutorial - code optimisation
« on: September 30, 2008, 01:45:41 PM »
Hi all,

Just advertising my new tutorial that discusses code optimisation (advantages and pitfalls) and the use of keywords like volatile, as well as introducing the use of data structures to reduce the amount of code you need to write.

I try to introduce how compilers perform basic code optimisation via my 'post boy' analogy. It's a bit cheesy but was the first thing I could come up with.

It's not an introduction to C.

For those of you who already know about these things - then I'd welcome any feedback or things to add. I will try to update it soon with some stuff about multi-threading - which is a lot more complex and relies on some of the key points in the tutorial.

Here it is: http://www.societyofrobots.com/member_tutorials/node/202

Webbot
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Steel_monkey

  • Full Member
  • ***
  • Posts: 85
  • Helpful? 0
Re: New Tutorial - code optimisation
« Reply #1 on: September 30, 2008, 04:11:45 PM »
Thst is really wonderful. It is like " I know this, but need to make some logic stricture". Great thanks.

Offline paulstreats

  • Supreme Robot
  • *****
  • Posts: 1,381
  • Helpful? 21
Re: New Tutorial - code optimisation
« Reply #2 on: September 30, 2008, 06:16:49 PM »
Great tutorial!

 It may be worth mentioning in the struct section that you cant pre allocate values to the internal variables, its obvious when youre used to using them but can be confusing for a beginner.

Also have you found a way of adding methods to typeDef's?

e.g.

typeDef {
            void setPattern;
}ledBar

where set pattern would call a function e.g.

ledBar bar1
bar1.setPattern()


.

I know that you can make an external function and then assign setPattern as a pointer to the function, but this means setting the pointer for every instance of ledBar created.
Its just something I thought of a couple of years ago but never gotten around to looking at properly, im not sure that it can be done since it means predefining the pointer or function within the typeDef.


Offline WebbotTopic starter

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: New Tutorial - code optimisation
« Reply #3 on: September 30, 2008, 07:46:26 PM »
Also have you found a way of adding methods to typeDef's?

e.g.

typeDef {
            void setPattern;
}ledBar

where set pattern would call a function e.g.

ledBar bar1
bar1.setPattern()


.

I know that you can make an external function and then assign setPattern as a pointer to the function, but this means setting the pointer for every instance of ledBar created.
Its just something I thought of a couple of years ago but never gotten around to looking at properly, im not sure that it can be done since it means predefining the pointer or function within the typeDef.



It's called C++  ;)
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline WebbotTopic starter

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: New Tutorial - code optimisation
« Reply #4 on: September 30, 2008, 07:51:15 PM »

 It may be worth mentioning in the struct section that you cant pre allocate values to the internal variables, its obvious when youre used to using them but can be confusing for a beginner.


Sorry I'm slightly confused (actually I spend most of my life in this state!).
You can initialise the struct data members when they are defined - so please clarify what you mean by 'pre-allocating internal variables' - just so we know what we are talking about. Example?
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline paulstreats

  • Supreme Robot
  • *****
  • Posts: 1,381
  • Helpful? 21
Re: New Tutorial - code optimisation
« Reply #5 on: October 01, 2008, 04:35:02 PM »
hey,

 if you do this:

typeDef {         //define a new "type"

   char direction:1 ;   
   unsigned int speed = 0;
   unsigned int duty;
   unsigned int pidcounter;
   unsigned char enabled:1;
} leftmotor;

the int speed has a predefined value of 0. This wont pass through a compiler (or never used to)

Offline WebbotTopic starter

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: New Tutorial - code optimisation
« Reply #6 on: October 01, 2008, 07:26:56 PM »
Ok - understand now
I think that if you want to initialise data then you can either do it when declaring the variable (not the type) ie

typedef struct s_motor{
   char direction:1 ;   
   unsigned int speed;
   unsigned int duty;
   unsigned int pidcounter;
   unsigned char enabled:1;
} MOTOR;

MOTOR leftmotor = {0,0,0,0,0};
but this means you have to supply the values every time.


or you could have a global 'init' method which you MUST call for each new instance:
void motor_init(MOTOR* motor){
  motor->speed = 0;
}
which could do some more complex stuff that would be hard in the previous example.
I prefer the 'init' method. Since you cannot allocate new MOTOR instances on the fly (they have to be global variables) then it's no great hardship. If you have lots of MOTORs then they can be in an array and your 'main' just calls the 'init' method for each MOTOR in the array.


C++/Java really help with this sort of stuff - as per my C++ tutorial. But most folk don't seem to want to use OO languages - so if you want a non-OO language like C then you have to put up with its disadvantages.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline paulstreats

  • Supreme Robot
  • *****
  • Posts: 1,381
  • Helpful? 21
Re: New Tutorial - code optimisation
« Reply #7 on: October 02, 2008, 04:12:57 AM »
Hi, Ive got myself setup with lots of similar functions It gets quite confusing sometimes (especially when I look through code I wrote a couple of months ago and couldnt be bothered comment it ;D)

Quote
But most folk don't seem to want to use OO languages

I'm quite into Java for PC applications at the moment - the OTF compiler is getting faster with every release, but OO for microcontrollers is always a let down in my experience. Even the OOPic which is designed specifically for OO programming is a let down. (The only actual objects that can be instantiated and used are ones that are predefined by the language developers, meaning that you can't make your own objects. This has been a similar story with many short lived C++ compilers for microcontrollers).

I made a multitasking system for PIC not long ago but without any external memory, storing just a few tasks or threads worth of return stacks aswell as thread properties pretty soon uses up all of the onboard SRAM. I built an external SRAM onto one of my developing boards to use it but not everyone is willing to go to them lengths... Especially when you have to have 2 i2c controlled i/o expanders to use the external sram along with building a sending / retrieving system for it. Trying to do something which should be simple like a multi tasking system can end up being a lot of extra work :(

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,657
  • Helpful? 169
    • Society of Robots
Re: New Tutorial - code optimisation
« Reply #8 on: November 09, 2008, 06:10:08 AM »
Ok I finally got the time to read this (read: got off my butt). I love it!

A lot of the stuff I had learned way back in college when learning C++, but forgotten a lot of it. A great refresher =)


general comments/questions
Is there a way to store more stuff in ROM to save more RAM, or vice-versa?

Why aren't recursive functions allowed on an mcu - is it just a RAM limitation?

And how do recursive functions affect optimization? (notice the 'z', hehe)

Perhaps add a description of memory leaks?

How does optimizing code affects its readability for a programmer?

Ok now for my comments, divided up into each section . . .

01 - Segmentation
How many stacks an mcu has vs computers? 1 vs many, right?

So if a variable is not initialized, its stored in a different location? gcc says it initializes all variables to 0 if the user doesn't assign value.

There are a lot of steps going on here, can you draw up a graphical diagram representing it somehow with bubbles/arrows? Basically to reinforce what we read. Like for the fragmentation, perhaps draw a few squares with memory shading?

For dynamic allocation . . . I really wish mcu's had this . . . I only give it time until it's implemented in some new AVR :)

Don't forget EEPROM as another form of memory! Nonvolatile like ROM but can be changed like RAM.

So not just variables are stored in RAM, but also stack info in the same location?

02 - Optimisation fundamentals
Ok I'm halfway finished reading section 2 and its so far clear to me. But I just got a call from some people to go out for dinner so I'll post this now and post more comments a later day. I really need to read up on pointers and malloc again . . . my brain has atrophied when it comes to PC programming . . . too much embedded programming for me . . .

Offline WebbotTopic starter

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,132
  • Helpful? 108
Re: New Tutorial - code optimisation
« Reply #9 on: November 09, 2008, 12:49:59 PM »
I'll answer some of your questions in this post (partly as an aide-memoire for me!) and will get around to updating the tutorial as soon as I can. But it will save you having to re-read the tutorial to try to spot the answers.

Quote
Is there a way to store more stuff in ROM to save more RAM, or vice-versa?
The biggest candidate is any string constants. So for example if you keep logging with something like:
Code: [Select]
rprintf("Sonar distance=%d\n",sonarValue)Then the string "Sonar distance=%d\n" never changes so you can use some macros to store the string in Flash (Program memory) rather than in RAM which is where it will go by default. So your program is bigger but needs less RAM at runtime. Will give a fuller explanation in the tutorial.

Quote
Why aren't recursive functions allowed on an mcu - is it just a RAM limitation?
The problem is that the Stack must be stored in RAM and an mcu doesn't have much. Each level of recursion will need more memory for the stack. However: recursion is allowed - but you just have to keep it small. So for example: this should print the numbers one to ten:-
Code: [Select]
void one2ten(int num){
   rprintf("Num=%d",num);
   if(num <= 10){
       one2ten(num+1);
   }
}
void main(){
   one2ten(1);
}
If you don't know how many levels deep your recursion will go then you are in danger of running out of stack space and the code going beserk.

Quote
And how do recursive functions affect optimization?
They don't. The compiler just optimises individual methods and individual lines of code. The compiler may be completely unaware that any of your code is recursive.

Quote
Perhaps add a description of memory leaks?
Memory leaks are caused by dynamically allocating memory and then forgetting to release it once you have finished with it. The tutorial alrerady discusses how gcc only allows short lived dynamic memory allocation and automatically frees up the memory at the end of the method that allocated it. So, in theory, I can't think how it would be possible to have a memory leak with gcc.

Quote
How does optimizing code affects its readability for a programmer?
If you are optimising the code by using the compiler -O settings then your source code doesn't change - so readability is compromised. However: you can sometimes help the compiler when evaluating complex expressions. For example:-
Code: [Select]
  double d =  (x * sin(theta)) + (y * sin(theta))
Calculating sin(theta) is a time consuming operation and its done twice. Depending on the optimisation settings of your makefile, and the capability of the compiler, it 'may' notice that its done twice and reinterpret your equation as:
Quote
   double d = (x + y) * sin(theta)
Alternatively you could change the source code yourself to hand optimise the equation. You may even store partial results within temporary variables so that they aren't recalculated. Obviously your decision to change the source code may mean that it is less legible - but this could be a necessary evil in the quest for better speed.


Quote
How many stacks an mcu has vs computers? 1 vs many, right?
mcus are normally run in a single threaded environment so there is only one stack. Whereas your computer may be running lots of programs at the same time and so each program needs its own stack. Luckily computers have a lot of RAM so this is possible. But an mcu has limited memory so it is more difficult. Multi-tasking environments do exist for mcus but normally require you to set a maximum stack size for each thread. So if you say use 100 bytes and you have 3 threads then it will allocate 300 bytes for the stacks. When it switches threads it will change the stack pointer to point to the 100 bytes that are solely used by that thread.

Quote
So if a variable is not initialized, its stored in a different location? gcc says it initializes all variables to 0 if the user doesn't assign value.
The unitialised variables in the BSS segment (immediately after the end of your initialised variables) are all zapped to zeroes just before your 'main' is called. This means that numeric variables are all set to zero and strings are of a zero length.

Quote
can you draw up a graphical diagram
Will do
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

 


Get Your Ad Here

data_list