Shop OBEX P1 Docs P2 Docs Learn Events
Program is too large. How do I make it smaller? — Parallax Forums

Program is too large. How do I make it smaller?

jeff-ojeff-o Posts: 181
edited 2011-06-17 09:43 in Propeller 1
I'm working on a pretty complex program (at least for me!) that is too large to fit. At the moment it is too large by 100 longs. Inefficient programming? Likely. But there's still a bit of code that I need to add, so I need to drop some weight. I'm doing what I can to reduce it's size; here's what I've done so far:

Moved common instructions to functions so that I'm not repeating code. There may be more that I can do here, I will have to stare at it more.

I'm writing a lot of stuff to a 4x20 LCD screen. I found that it took less space to write the text to screen using a single string, rather than writing each line with a separate string. So that's what I did.

I've got a 64K EEPROM, so some variables that only need to be read at startup are stored there. I think I could store more strings in there to save program space.

Redundancies removed where possible...

So what else can I do? I need to stick with spin code only, since I don't know how to write in assembly. Got any tricks that I could try? Thanks!!

Comments

  • ElectricAyeElectricAye Posts: 4,561
    edited 2011-06-12 13:07
    Maybe if you post your code, somebody here can give you some hints.



    attachment.php?attachmentid=78421&d=1297987572
  • Mike GreenMike Green Posts: 23,101
    edited 2011-06-12 13:19
    There's no simple answer to how to make a program smaller. Some of it consists of things that you've mentioned like moving duplicate code to functions. You mention writing separate strings as one string instead. You might also consider finding other ways to simplify strings and avoid duplication of strings. Since you have a 64K EEPROM, you could keep the strings in the 2nd 32K of the EEPROM, perhaps writing them there using a separate initialization program that's just executed out of RAM using the Propeller Tool.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-06-12 13:34
    Hi Jeff,

    I haven't seen much code that needs all the 32kB except VGA-double-buffers.
    Do you use real big stack-variables?
    I mean
      long MyStack1[ 500]  
      long MyStack2[ 500]  
      long MyStack3[ 500]  
      long MyStack4[ 500]  
    
    There is an object to measure the needed stacksize.

    Did you check the value-range of the variables you use?
    especially arrays
    If the value-range stays within 65535 you can change the variable-type to word saving two bytes compared to a long
    If the value-range stays withing 255 you can change to variable-type to byte saving three bytes compared to a long
    Did you already store ALL strings in the upper 32kB?

    Best thing would be to post your entire code. But maybe you don't want to.
    Anyway how many kB do all the strings need in your code?
    (throw out the guitar user manual shown on the lcdisplay ;-)

    best regards

    Stefan
  • localrogerlocalroger Posts: 3,452
    edited 2011-06-12 15:00
    As ElectricAye says it's kind of hard to be real helpful without some idea of how your code is structured, but I can add a couple of things to the suggestions already given...

    Delete any unused methods in objects you're using. (Brad's Spin Tool has a setting to do this for you if you use it insead of the PropTool.) A lot of "features" are actually code you're not using. I find I end up with special versions of nearly all objects for various projects because of this kind of optimization.

    Reuse PASM images after the cogs are launched. This is actually kind of a pain in the rear end to do in Spin but it is possible; add functions to objects with PASM images to return the image location and length, and use direct memory access to reuse that memory for storage. Using a PASM image for a video buffer is a big win.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-12 15:35
    Full disclosure: the code is written with 12blocks. That means I give up some efficiencies I suppose, but as a n00b programmer it means the difference between getting my project done, and letting it languish on my shelf. I think the biggest issue with 12blocks in terms of memory use is that all variables and all array entries are longs, regardless of what is stored in them. I need to look at the built in blocks to see if I can make special byte sized and word sized versions.

    At the moment not all my strings are in the upper 32K of memory. I'll move them tonight to see if that helps. I'll also post code then (I'm posting from an iPhone now)
  • localrogerlocalroger Posts: 3,452
    edited 2011-06-12 16:04
    Tools like 12blocks are great for jumpstarting into a new and possibly intimidating environment, but they tend to have costs associated with them. This is one of those costs. It can be very hard to optimize code written through a high level front-end that is trying to be too helpful.

    If you feel up to the task, I'd suggest porting your project to Spin and the underlying OBEX objects 12blocks uses to provide I/O. If you've got the logic debugged this is half the battle, so you can concentrate on implementing working functions in the new environment and syntax.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-06-12 18:21
    localroger said
    Delete any unused methods in objects you're using. (Brad's Spin Tool has a setting to do this for you if you use it insead of the PropTool.)

    I'll second that - I've found that can save hundreds of longs, sometimes even double the code space.

    Then again, I ran out of code space years ago, which is why I moved over to C on the propeller. Drop in the appropriate memory chip (64k, 512k or 32Mb) and there is always enough free memory.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-12 18:26
    I'm out of the woods for now, simply by moving most of my strings to the upper 32k. Hopefully that'll leave enough free space to add the last feature I need.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-12 18:29
    Oh! And I'll post my code once I add a few more comments. The code generated by 12blocks is actually plain old spin; as long as you have all the dependent files in the right folder it will compile and load from the Prop tool without modification.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-12 23:27
    Right. Well, I was having trouble reliably reading my arrays from memory, so I tweaked the memory management settings for a while until it was happy. I freed up more space by moving one of my custom objects into an existing object. I also had one extremely large string that I was basically trying to use as an array of smaller strings - this did not work so well. I think the propeller (or something) was choking on it, so I split it up into chunks and it seems happier with that. It'll mean a bit more coding to extract the strings I need, but it's not too bad.

    One thing that helped in all of this (for anyone traveling the same path as me) was to build a small program that basically spits out all of the used and free memory in the upper 32K of EEPROM. I noticed some strangeness (including negative space remaining, presumably an overflow) that led me to suspect some of my memory location settings were not correct.

    And now it is very late and I really should have gone to bed two hours ago. I'm gonna pay for this tomorrow...
  • WBA ConsultingWBA Consulting Posts: 2,935
    edited 2011-06-13 00:06
    What method did you use to store the strings in the upper 32k? I have seen several examples but haven't actually played with any yet. (I would like to do the same in one of my projects)
  • jeff-ojeff-o Posts: 181
    edited 2011-06-13 04:55
    I used Memory_store_management by Brandon Nimon. I've attached the exact object I used; it's been modified with 12blocks xml and the data addresses I used are for an EEPROM that is larger than 64K - I've actually got a 128K in here. If you use it, be sure to reduce the amount of data space that is allocated to match the EEPROM you're using. There are also some other files you'll need, so be sure to download the actual Memory Storage Management object from the OBEX.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-16 05:19
    I ran out of memory again. I managed to squeeze it all in at one point, but at present I'm over by about 70 longs. The I'm not sure where else to trim! Another problem I was having before when it did all "fit," was that the prop would not load from the EEPROM during a cold start, it would only work from RAM. Not sure why.

    Anyway, here's my code which I am releasing with great reluctance. I tend to hold my cards close to my chest, especially on something I've been working on for months. All of this will be released officially this summer, so please don't steal it ok? ;)

    Attached are my main three program files in .12b format. These will open just fine in the prop tool, but open them in 12blocks to really see what's going on. Also included are all the various objects needed to compile the project.

    So yeah, if you're interested in having a go at my code, please feel free. Any help in compacting it a little would be greatly appreciated.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-16 09:49
    jeff-o,

    Is there a way to convert the 12blocks files to Spin? I have never used 12blocks before, so I installed it and tried to use it. I was able to view your source files, but I'm not able to view them as Spin files. I get an error from 12blocks saying that it can't save the file because of some XML error.

    BTW, 12blocks looks interesting, but it reminds of the first time I used a Mac computer. I kept hoping I could find a DOS prompt.

    Dave
  • jeff-ojeff-o Posts: 181
    edited 2011-06-16 10:11
    Hmmm, if you want to compile with spin I think there are a few more files that 12blocks uses when it compiles. Basic stuff like working with strings and delays and whatnot. I'll have to look at what other dependencies it has (though they are listed in the OBJ header). However, you should be able to just open the .12b in the prop tool after renaming to .spin.

    If you're still having trouble I will export my original files to .spin and post them. I also need to upload my custom hardware file that goes into 12blocks' hardware folder...
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-16 10:30
    OK, I see that the 12b files are standard Spin files. I'll try to build it when I have a chance. Have you tried BST? That should probably free up some memory by removing unused methods, folding constants, etc.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-16 10:59
    I was thinking of trying it. It would mean leaving the cozy environment of 12blocks to actually do the compiling and uploading, but I'll do it if I have to!
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-16 13:26
    I built Prism MkII Complete with the Prop tool and it used 3,314 longs for program, 4,412 longs for variables and 462 longs were unused. I also built is with BST, and it saved about 700 longs with a total of 1,167 longs that were unused.

    Most of the 3,314 longs of variables are in the VAR space used by the four instances of Karplus-Strong. You could save space with fewer instances, or reduce the size of the buffer it uses.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-16 13:57
    Awesome! I suspect that part of your success is due to the fact that I reduced the buffer size of the Karplus Strong object before posting my files. It's something I'd been playing around with but wasn't satisfied with just yet. The main reason is that reducing the buffer seemed to change the pitch of the strings! For reference, 96000 sampling rate and a buffer size of 1680 is pitch-perfect. I have to play around with it more tonight; perhaps reducing the sampling rate as well as the buffer will be the key to success. I was concerned about loss of audio fidelity but I think it'll be OK.

    I need all four instances of Karplus Strong though - one per string, all running at the same time. I'm especially excited about BST though, that will give me some breathing room.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-16 15:13
    I think the buffer size determines the minimum frequency you can handle, which is the sample rate/buffer size. So your minimum frequency would be 96000/1680 = 57 Hz. A sampling rate of 96,000 sps seems awfully high. Maybe you can lower it to 48,000 or lower. This would give; you a lower minimum frequency, or you could reduce the buffer size even more.

    I may be wrong about the buffer size thing. You should contact lonesock to find out for sure.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-16 19:24
    Interesting; it would seem that if I reduce the sampling rate, I also need to reduce the buffer by the same factor. Otherwise the pitch is wrong. That still saves me tons of space, though.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-17 06:29
    I don't think the buffer size or sampling rate have any thing to do with the pitch, except that they determine the upper and lower frequencies.
  • jeff-ojeff-o Posts: 181
    edited 2011-06-17 08:08
    I didn't think so either. But is sure changes how it sounds for me. Perhaps there's something else being affected though (like my routine that checks the fret position) that is the culprit.

    After reducing the sampling rate and buffer size I'm able to compile in 12blocks again, or in BST (love BST btw, kicking myself for not trying it sooner!)
  • jeff-ojeff-o Posts: 181
    edited 2011-06-17 09:43
    Confirmed: The size of the buffer and the sample rate have no effect on pitch, as long as the buffer is large enough to handle the lowest note being played. It was indeed something else mucking things up.
Sign In or Register to comment.