Binary too large for RAM
MGreim
Posts: 114
Hi,
My program is quite big in between and i am running in the message as shown above.
I switched to the BST compiler, which was automatically removing unused SPIN code etc. , but now i am in the same situation as before.
Any (general) hints how to optimize the code?
I have one bigger "main" program and 5 other cogs running some smaller tasks.
How could i optimize the RAM usage?
Markus
P.S. i have just compiled the new C++ based command line compiler under Linux.
Its running fine but not optimizing in any way.
My program is quite big in between and i am running in the message as shown above.
I switched to the BST compiler, which was automatically removing unused SPIN code etc. , but now i am in the same situation as before.
Any (general) hints how to optimize the code?
I have one bigger "main" program and 5 other cogs running some smaller tasks.
How could i optimize the RAM usage?
Markus
P.S. i have just compiled the new C++ based command line compiler under Linux.
Its running fine but not optimizing in any way.
Comments
What size stacks have you reserved for yor objects? Perhaps you have a few longs to save by pruning stacks to the minimum required.
Do you have a lot of PASM code? If so you can save space by extracting the compiled PASM as binary blobs. Save those blobs on SD card if you are using one or in the top of a 64k EEPROM. Load that PASM at start up via RAM buffer that can be recycled.
May be use two Props.
1. Use built-in operators. SPIN is rich with operators and it's often possible to push a lot of logic into operators.
2. Inline functions which are only used once.
3. Audit your stack usage and make it as small as possible.
PASM:
1. Can the DAT space be reused?
General:
Any large tables or buffers which can be optimized?
If BST provides a LIST style output, check the code usage and start with the biggest users.
Plus - any chance of posting the code as a .zip file? Others here on the forum are expert at the art of optimisation.
And then you could look at C running in XMM mode where the program is stored in external memory. I've routinely run programs between 100k and 500k this way, though they do take a while to download as the size goes up.
What hardware did you attach? Do you have an SD card? Do you have a 64k EEPROM or maybe more?
Do you have to deal with text? Error-messages/status messages/menus/help-text?
Is it necessary to have all code in memory at the same time or can it be swapped because only parts are needed in one point of time?
Do you make good use of extracting repetitive things into functions?
If possible you should really zip your sources and post them here.
- I have no SD card. Its the classical Propeller design but i can use a bigger EEPROM
- I am using the <S6B0724 Version 1.0> display driver which in a modified version. In this display driver smaller sized fonts are coded in a DAT field.
For the big letter size the driver is using the built in font.
First i will try to remove all unused letters out of the font.
- HEATER is writing something about binary BLOBS. But i didn't really understand what he is talking about.
- I have also a lot of text in a DAT field . Any chance to handle this more RAM saving.
Thanks
Markus
The compiler switches have been -l for the list file and -Ogr for removing unused spin code
The last address is $37D0 = 14288 decimal
As far as i know the listing is counting the address in bytes.
The Propeller has 32KByte of RAM , so where is all the other RAM gone???
Whats my mistake here????
----
Object Address : 0010 : Object Name : vx1
Object Address : 108C : Object Name : ST7565READOGM128
Object Address : 210C : Object Name : rad
Object Address : 21F8 : Object Name : Quadrature_Encoder
Object Address : 2300 : Object Name : TickTock
Object Address : 2414 : Object Name : busEngineTE
Object Address : 2828 : Object Name : tx1
Object Address : 2C10 : Object Name : VinculumSPI
Object Address : 30B8 : Object Name : format_memory
Object Address : 31D0 : Object Name : ax1
Object Address : 3580 : Object Name : pulse
Object Address : 363C : Object Name : votcheck
Object Address : 36AC : Object Name : date_time_ts
Binary Image Information :
PBASE : 0010
VBASE : 37D4
DBASE : 3FF4
PCURR : 0243
DCURR : 3FFC
Your real program only has a buffer for loading the PASM code from EEPROM into RAM, then starts the PASM, waits until it is running and uses the same buffer for loading the next driver...... after loading all the drivers you can use the buffer for something else for example as screen-buffer.
I think I already described this in one of my blog-entries.
Additionally you could reserve 1 or 2 slots of upper EEPROM for your strings. Same procedure over here. One buffer for loading the actually needed string. You can have a printMessage function, which first loads the message you want to display from EEPROM and then prints it on your output-device. As a user you won't notice the difference, as loading these short messages does not take a long time.
You don't see this reserved memory in the BST-listing because it's reserved with the _stack directive.
So you can save the most memory if you write a new display driver which needs no display buffer in the hub-ram. But this is a big task.
Andy
BTW are you using a USB thumbdrive attached to the Vinculum? You could park text there and read and use as needed. Although that takes some headroom to get it off the drive.
thats it, i think !!!
I have adapted the S6B0724 object to the EADOGM series (see www.lcd-module.de/pdf/doma/dog-m.pdf ) and also published my modified driver
anywhere here in the forum 2 years ago. I never thought about the _stack option there.
I think 16 kByte are not necessary at all, because the S6B0724 as well as the ST7565R controller of the EADOGM has only 1 KByte of RAM (128 x 64 pixel)
Is _stack a special control word (i don't think so) ? Or simply a pointer to the display ram?
Thanks a lot !
Markus
What I mean by "binary blobs" is as follows:
If you are running a lot of PASM code in many COGs then that code occupies
space in your binary. Often these COGs are loaded once at start up so that
results in up to 16K of space being wasted in the HUB area where the PASM code
was loaded from.
Wouldn't it be great if we kept all those bits of PASM in EEPROPM, say, loaded
them one by one from EEPROM at start up and started COGS with them. Via a 2K
buffer space somewhere in HUB. Then we have saved a max of 14K HUB space and can
still use that 2K buffer for something else when the main program runs.
To this end the BSTC compiler provides a -c switch that compiles a Spin module
throwing away all the Spin and just outputting the compiled binary.
That's the basic idea and there are many ways it can be implemented. Might be
too much work though if you can find space more easily.
T Chap,
It is not necessary to comment out all the unused methods when using the BST
IDE. It has an option to leave unused methods out of the compiled binary.
It may be that BST is not reporting the full size because of the size error. It may just be showing the size object that causes the failure, or all of the previous objects before including the large one.
Do you have the large array defined on the stack or is it defined as a VAR or DAT variable?
EDIT: I ran a test with an object that allocates a large chunk of memory in DAT, and I get the message "Binary too large for RAM by 353 Longs". I also get a blank listing file. What exactly does your error message say? This would really be a lot easier if you just posted your code.
Finally it was really a statement
_stack = $4000 >> 2
In my main program.
I had copied it months ago from an example program to test my graphic driver.
The reference manual says: .. it is good practice to do this to get a compiler error instead of a memory overflow at runtime.
I have now reduced the stack to 1000 longs, and everything is fine gain.
Any idea what a typical stack size is?
If you have no recursion etc. it seems for me that 100..200 longs should be ok?
Regards
Markus