CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ROM, RAM and optimiser...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
TorAtle



Joined: 03 May 2004
Posts: 5

View user's profile Send private message Send e-mail

ROM, RAM and optimiser...
PostPosted: Mon May 03, 2004 7:07 am     Reply with quote

PIC16F877.

Question: when near the limits of RAM usage, why does ROM start to suffer? I am trying to understand what the optimiser is thinking. Scenario:

ROM=7361, RAM worst case=276

Introducing int16 test[20] globally makes perfectly sense - ROM=7369, RAM worst case=316 (87%)

However increasing the size of the array above 20 will result in ROM usage, and I get out of ROM very quickly.

I can only assume that even though it looks like there's more RAM available the compiler makes use of it for optimising purposes. Can anyone shed any light on this and perhaps offer any workarounds?
SteveS



Joined: 27 Oct 2003
Posts: 126

View user's profile Send private message

PostPosted: Mon May 03, 2004 7:41 am     Reply with quote

I think I know why, but I'm not sure; but here's how to figure it out:

Compile both ways and compare the listings. Then you'll know exactly what the compiler was thinking...

I suggest "Freediff" at http://www.saltybrine.com/ if you don't already have a file compare program.

- SteveS
TorAtle



Joined: 03 May 2004
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Mon May 03, 2004 8:26 am     Reply with quote

Not very easy to see, as the addresses at the beginning of each line differs from a certain point and thus makes everything after that point "different".

I have 5 int16 arrays (none of them large). From what I could see, it moved one of them from one bank to another.

Btw, there's only one function which uses these arrays, and it takes a pointer to one of them as input. Could the code of this function be duplicated or something like this due to the input parameter pointing to different memory banks?
Ttelmah
Guest







Re: ROM, RAM and optimiser...
PostPosted: Mon May 03, 2004 8:28 am     Reply with quote

TorAtle wrote:
PIC16F877.

Question: when near the limits of RAM usage, why does ROM start to suffer? I am trying to understand what the optimiser is thinking. Scenario:

ROM=7361, RAM worst case=276

Introducing int16 test[20] globally makes perfectly sense - ROM=7369, RAM worst case=316 (87%)

However increasing the size of the array above 20 will result in ROM usage, and I get out of ROM very quickly.

I can only assume that even though it looks like there's more RAM available the compiler makes use of it for optimising purposes. Can anyone shed any light on this and perhaps offer any workarounds?

The obvious 'probability', is that the compiler is having to add more RAM bank switching, when extra variables are added. It prabably shifted something else, used more commonly, into another bank, to make room for the array. You can often 'improve' things yourself in this regard, by declaring registers that are used a lot early in the code, and thereby placing these in bank0.

Best Wishes
Guest








PostPosted: Mon May 03, 2004 3:13 pm     Reply with quote

Ttelmah,

thanks a lot for that advice, you were spot on!

After some head scratching I came to the conclusion that finding the optimum memory bank for all the variables would be an impossible task, so what to do? Brute force!

I now have a little utility crunching away, testing every combination. Only 5% done so far but already I've saved over 300 bytes. That's about 5% less program memory used. Will report the final result when the utility is done.
TorAtle



Joined: 03 May 2004
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Mon May 03, 2004 6:34 pm     Reply with quote

Sorry for failing to log in before my last post (above).

The utility I mentioned is now finished. First of all - the algorithm was flawed Embarassed. It didn't go through all the combinations, not even close. In my case I had 72 global vars, the utility tested 72*71 combination. The correct answer is 72!, so quite a long way from it.

The idea was ok, though. In my case the difference between worst and best case was around 800 bytes (not including those combinations who resulted in 'out of rom'), or 10% of total program memory.

At this point I am unsure how to make a more clever algorithm, or in fact it it's worth the trouble. Two approaches that might yield reasonable results:
1) Count and sort the global vars; most used at the top.
2) Random order. Stop the utility when you're satisfied with the result.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 04, 2004 1:49 am     Reply with quote

This is a great idea! A tool for computing the optimal memory layout!

How did you do this?
Do you have all your global variables in a separate file and are you shuffling the lines in this file around?

I try to implement my programs with the concept of object orientation in mind, so I have a lot of separate files. I don't like to have my global variables in one single file, but in the CCS compiler this seems the only way to have some control over the memory layout. I also like to make some variables static to a function but ran into the same memory mapping problems.

What if we can play around a bit with your idea of a tool, and then ask CCS to integrate it in the compiler? The compiler is much more versatile and knows about all global variables, then you don't have to collect them in a single place but can scatter them all over your source files where they belong.
I like this concept! Razz

Of course it should be possible to turn this optimization on/off.
Ttelmah
Guest







PostPosted: Tue May 04, 2004 2:04 am     Reply with quote

TorAtle wrote:
Sorry for failing to log in before my last post (above).

The utility I mentioned is now finished. First of all - the algorithm was flawed Embarassed. It didn't go through all the combinations, not even close. In my case I had 72 global vars, the utility tested 72*71 combination. The correct answer is 72!, so quite a long way from it.

The idea was ok, though. In my case the difference between worst and best case was around 800 bytes (not including those combinations who resulted in 'out of rom'), or 10% of total program memory.

At this point I am unsure how to make a more clever algorithm, or in fact it it's worth the trouble. Two approaches that might yield reasonable results:
1) Count and sort the global vars; most used at the top.
2) Random order. Stop the utility when you're satisfied with the result.


A brilliant idea.
The amount of the saving, is pretty impressive, even with the 'flawed' code, and relative to the versions you couldn' compile (with 'out of ROM'), must be even higher.
I think option '1', will do most to improve performance, so using this to choose between the best half dozen solutions, would seem to be a good 'performance/space' compromise solution.

Best Wishes
TorAtle



Joined: 03 May 2004
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Tue May 04, 2004 6:03 am     Reply with quote

I have implemented the other 2 approaches I mentioned:

1) Count & sort - very good. Did better in my case than the flawed BruteForce method by 4 bytes...
2) Random - I won't say "better" or "worse" but I let it run overnight and it produced the best result. The reason for this is of course that it found a better combination than the flawed BruteForce. By luck! :-)

So...the Count&Sort looks like the best option - it's very fast and produces a good result.

I can clean up the code a bit and include all 3 methods if anyone would like to play?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 04, 2004 6:46 am     Reply with quote

Sounds good! I'm interrested in the count&sort method.

Thanks for sharing this knowledge with us!
TorAtle



Joined: 03 May 2004
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Tue May 04, 2004 9:01 am     Reply with quote

http://home.c2i.net/toratlel/opt

Get opt.exe and save it in your project folder. To use the Count & Sort method, you will also need grep.exe and wc.exe, so download these too.

Grep.exe, wc.exe and also ccsc.exe (the compiler) must be somewhere referenced to by the %PATH% environment variable.

What you need to do:
Backup your files first!
1) Move all the global vars to <MyProject>.h

No tab's. Comments must ble placed after the declaration like so:
int16 iNumber; // comment here
Clear lines will degrade speed for the flawed BruteForce method.

2) Move all #define's and struct definitions to <MyProject>_define.h

3) Include those two files in your main source code file like so:
#include "myproject_define.h"
#include "myproject_opt.h"

Run opt.exe in a console window. To see the options, just run opt.exe without any arguments.

Let me say straight away that error handling is limited. If you have any questions or get any error messages you can't sort then email me at [email protected]
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group