Shop OBEX P1 Docs P2 Docs Learn Events
Binary too large for RAM — Parallax Forums

Binary too large for RAM

MGreimMGreim Posts: 114
edited 2012-01-29 10:47 in Propeller 1
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.

Comments

  • Heater.Heater. Posts: 21,230
    edited 2012-01-28 11:32
    Without seeing your code or even knowing what objects you are using it is hard to advise on optimizing it.

    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.
  • ericballericball Posts: 774
    edited 2012-01-28 11:38
    SPIN:
    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.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-01-28 14:22
    All of the above excellent suggestions.

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-01-28 14:25
    Are you using more than one serial port? There are several variations of Tim Moore's four port driver around.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-01-28 15:46
    It's hard to give you some good advice without knowing the code or at least what kind of application we talk about. What's the kind of things running in the other COGs? Is it running continuous or is it started from time to time? SPIN or PASM?
    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.
  • MGreimMGreim Posts: 114
    edited 2012-01-29 03:01
    Many thanks for all the hints so far.
    - 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
  • MGreimMGreim Posts: 114
    edited 2012-01-29 03:54
    Below a part of the the header of the bstc list file.
    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
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-01-29 04:20
    What heater means is: extract all the DAT-sections which hold PASM drivers/programs into their own little EEPROM-writer programs. These EEPROM writer-programs simply store the PASM code in upper part of a 64kB EEPROM. I'd suggest to simply divide the EEPROM in 2kB slots. So, even if you have to change the PASM code (increase) the driver still fits in the same slot.
    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.
  • AribaAriba Posts: 2,690
    edited 2012-01-29 05:15
    MGreim wrote: »
    ...
    The Propeller has 32KByte of RAM , so where is all the other RAM gone???
    Whats my mistake here????
    The Demo for the S6B0724 object reserves 16kByte Display buffer, I guess you have done the same in your code, and this may be necessary for the display driver.
    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
  • T ChapT Chap Posts: 4,223
    edited 2012-01-29 05:58
    Rename and resave all your objects, then go through them and comment out all the unused methods. Phip P has a program somewhere around here called CLEAN that may accomplish the same task automatically(although it gets rid of all comments too).

    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.
  • MGreimMGreim Posts: 114
    edited 2012-01-29 05:59
    Hi Ariba,

    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
  • Heater.Heater. Posts: 21,230
    edited 2012-01-29 06:16
    MGreim,

    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.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-01-29 06:17
    I ran a test with BST and the Spin tool where I allocate a large array on the stack of the first method of the top object. BST doesn't complain, and the starting stack address (DCURR) just wraps if I allocate a very large array, such as 10,000 longs (40,000 bytes). The Spin tools complains that I exceeded the limit of 4096 stack variables. I don't think the compilers will complain if a 16K array is allocated on the stack in another object. So I don't see how that's the cause of the "Binary too large for RAM" message.

    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.
  • MGreimMGreim Posts: 114
    edited 2012-01-29 10:47
    Thanks a lot again for all the help.
    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
Sign In or Register to comment.