Shop OBEX P1 Docs P2 Docs Learn Events
What is the recommended Stack Size for cogspin()? — Parallax Forums

What is the recommended Stack Size for cogspin()?

Hi,
it's unbelievable: I have been searching, but there seems to be no proper docu about cogspin()?

So how do you estimate the right size of the stack and are there differences between the different tools? I tend to use FlexSpin.

Thanks a lot, Christof

Comments

  • RaymanRayman Posts: 16,162

    I think it is difficult to say exactly how much you need because it depends on the code...
    Pretty sure you can overflow any size stack if you do some crazy recursion...

    Generally I use 1000 longs and that seems enough for any normal stuff...

  • Thank you, @Rayman! So for the time being I will switch from 200 to this more solid number 1000. :-)

  • RaymanRayman Posts: 16,162

    1000 is probably overkill, but saves one from thinking about it...

    If saving RAM is super critical, there is a code around somewhere that measures the actual stack used. Probably just fills stack space with something and sees what gets changed...

  • JonnyMacJonnyMac Posts: 9,748
    edited 2026-03-10 17:57

    I only use canonical Spin (PNut or Spin Tools), but I think this will apply to byte code use of FlexProp.

    I tend to start with 64-128 longs depending on the complexity of the Spin cog in use -- which, in my case, is usually small.

    A couple years ago I was porting my 8-ch servo driver to the P2 and having some weird problems (that turned out to be unrelated to the servo code) so I wrote a little stack monitor object. If you're using this with an external object that uses a Spin cog you need to add a method to your object -- it tells the monitor the size and location of your stack.

    pub stack_details() : addr, size
    
      return @stack, STACK_SZ
    

    The stack monitor code will fill the stack with a test pattern which will be used later to examine & estimate stack use. I did a small clean-up of the stack monitor code and have attached it with a demo.

    I added a couple of stacked calls that are easy to play with to see the affect on the background cog stack.

  • bob_g4bbybob_g4bby Posts: 579
    edited 2026-03-10 18:58

    Flexprop compiles this and runs, using 6 out of 64 stack locations compared with Spin Tools 20/64 stack locations. Multitasking - could save a lot of space there too.

  • Yea, Flexspin ASM mode uses the stack in the same way (growing downwards), but will use a differing amount of space. it really depends - if your cog code is just a single function running a loop, it will likely use very little stack space because most values are going to be kept in cog RAM, but complex call graphs will likely use more stack. Some kinds of functions the optimizer likes and some will cause it to generate a huge pile of nonsense.

    For Spin bytecode (on any compiler) the amount of stack space required is very predictable. Each function call consumes a certain amount for its stack frame + space for all local variables and parameters. Then on top of that is control information used for REPEAT, CASE and other control structures and on top of that the value stack used to compute expressions.

  • (The typical stack size considered appropriate as a default on P1 is 128 longs, btw. 1000 is definitely overkill unless you know you need that much)

  • RaymanRayman Posts: 16,162
    edited 2026-03-11 00:09

    I typically start at 1000 and drop as needed…

    Maybe need:

    #define stacksafe 1000
    #define stackmin 128
    
    
  • JonnyMacJonnyMac Posts: 9,748
    edited 2026-03-11 01:58

    I've never used more than 128. Most often I use 64 and sometimes 32 (very simple cogs). The [user-defined] stack is only used for method call parameters and return values, so it doesn't have to be very big -- unless one is doing some very deep call nesting.

    Phil Pilgrim (RIP) discussed this topic a long time ago and provided code like what I use in my object. This was eye-opening and I found my Spin stacks could be much smaller than I thought I needed.

  • @JonnyMac said:
    I've never used more than 128. Most often I use 64 and sometimes 32 (very simple cogs). The [user-defined] stack is only used for method call parameters and return values, so it doesn't have to be very big -- unless one is doing some very deep call nesting.

    Local variables also go there. So if you call a method that has a big local array, that can easily exceed a small limit. That is the "you know you need that much" case.

  • JonnyMacJonnyMac Posts: 9,748

    You're right, local variables are a part of user-defined stack.

  • RaymanRayman Posts: 16,162
    edited 2026-03-11 07:45

    Sometimes when using other people’s objects, maybe you don’t really know how much it needs up front?

  • RaymanRayman Posts: 16,162
    edited 2026-03-11 07:54

    Wonder if stack monitor needs to all be in a cog…. Wouldn’t stack overflow corrupt Spin code in unpredictable ways?

    Maybe should have ability to kill a cog nearing end of stack?

  • JonnyMacJonnyMac Posts: 9,748
    edited 2026-03-11 15:39

    Wonder if stack monitor needs to all be in a cog….

    It is -- the stack monitor runs in the main code cog which allows it to read memory during different hub access windows that the other Spin cog

    Wouldn’t stack overflow corrupt Spin code in unpredictable ways?

    Yes. But the monitor is benign; it is only examining the contents of the defined stack to estimate how much of it has been changed.

    Again, this strategy came from Phil Pilgrim, someone I -- and I suspect most other forum members -- trusted very much. P1 memory is scarce, and using a tool like this helps me tune my stack sizes so that portions of RAM are not arbitrarily made unavailable. I have a couple P1 laser tag apps that will the P1 to the top of memory, and I am constantly looking for ways to trim fat to make room for more code.

Sign In or Register to comment.