Stack length problem
Enrique
Posts: 90
I just finished writing an object and decided to estimate its stack size using the Stack Length object.
·
During development I gave the stack size a value of 100 figuring it should be more than enough. I ran the Stack Length as indicated in the instructions and it came back with a Stack Usage of 11. I gave the program’s stack 15 longs, just in case, and ran again the exerciser. This time I got a message stating that the Stack Usage is 31. Gave the stack 35, ran the exerciser but the Propeller froze.
·
Went back to a stack of 100 and got back the same result: Stack Usage 11. I repeated this tests several times and always got the same results. When I give the stack 200 longs I also get back a Stack Length of 11.
·
Can someone explain what’s going on?
·
·
Thanks,
·
Enrique
·
During development I gave the stack size a value of 100 figuring it should be more than enough. I ran the Stack Length as indicated in the instructions and it came back with a Stack Usage of 11. I gave the program’s stack 15 longs, just in case, and ran again the exerciser. This time I got a message stating that the Stack Usage is 31. Gave the stack 35, ran the exerciser but the Propeller froze.
·
Went back to a stack of 100 and got back the same result: Stack Usage 11. I repeated this tests several times and always got the same results. When I give the stack 200 longs I also get back a Stack Length of 11.
·
Can someone explain what’s going on?
·
·
Thanks,
·
Enrique
Comments
I thought I understood the stack size problem... and I can certainly follow Mikes guidelines, but somehow I think I need to see a "stack for dummies" conversation[noparse]:)[/noparse]
Ok then.. from "someone else".
[noparse][[/noparse] Outrageous french accent ]
Listen very carefully, I shall say this only once..
[noparse][[/noparse]/ ]
Mike is absolutely spot on the money.
You _can_ estimate stack usage if you are careful.
Every method call requires 1 long for
a) the return parameter
b) each parameter
c) each local variable
+ the call itself (which is 4 longs)
Then, all your arithmetic evaluations require some stack depending on their complexity.
X1 := 1 + 2 + X3 + 4 would require 2 longs.
X1 := 1 * 4 / X3 +4 would require 4 longs.
It can be done.. it's not easy from the source, it's easier from a disassembly.
mmm.. that might be something fun to add to a compiler, a stack usage estimator.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pull my finger!
It looks simple for a single method. Once you get any kind of complexity in your program with methods calling other methods that maybe call off to a method in another object, then a couple of calls there before anything returns ... hopefully you get the picture. You can write a utility program that looks at the compiled Spin bytecodes for a program and does a worst case rough simulation of the program assuming that, if a call to another method appears somewhere in a method, that it will always be called at least once. The utility can make a worst case stack requirement estimate based on that call graph unless there's recursion. In that case, it can't tell because the stack requirement is data dependent (depends on the data processed by the program).
Oh, I agree completely, I was just pointing out that if you had an understanding as to how your algorithms worked you could do a rough tot up by hand.
It's not _easy_ but it's certainly doable.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pull my finger!
You must keep in mind that in all cases I run the object through the same paces, so this difference cannot be attributed to the fact that the program is going through different paths in each run. It should also be stated that the method that runs in the cog does not call other methods.
So, why am I getting these strange results?
Enrique
If yes and yes, then the display code is the thing that takes the largest stack and the 31/35 were because the display code overran the stack after they tried to measure it.
Also 4 long spare I found is too small unless you have no variation in the code path - no ifs, repeats, etc that are data dependent.
I suggest you post you object with the stacksize code in it so we can take a look, there could be other memory corruption issues that are not showing up in the running of your code but cause problems
The code that runs in that cog is made up of many repeat blocks with if statements in them.
I cannot publish the code as it is for a commercial venture.
Timmoore does make an interesting point in that he states tht the Stack Length object itself may be corrupting the stack.
REPEAT blocks with IF statements in them certainly use a few levels for the temporaries needed. Just how many depend on the complexity of the statements and how they're nested.
Certainly, just running the code under test does not always (I should more often than not) exercise code fully and therefore the stack use may not be fully used. There is probably no real way to absolutely to know what the stack usage will really be, so whatever you find, make sure you add plenty more unless you are short of space in hub. The results of stack overflow cause all sorts of funny things and are very hard to find - so if something happens, increase your stack to some enormous number first.
I published a debugger (spin and pasm) which will display the stack space used per spin instruction. Use the mode -2 version, not the mode -3 as the stack use cannot be calculated propery since this version interrupts the rom interpreter and by that time the original stack start pointer has been destroyed. (Look in the last few days threads).
VAR
long stack[noparse][[/noparse] 100 ]
becomes
VAR
long stack[noparse][[/noparse] 50 ]
long dummy[noparse][[/noparse] 50 ]
and seeing how that affects what the Stack length object returns.
It could be there is some flaw or limitation in that object or the way you are using it causes the problem, or any number of things. Without some source code to demonstrate the problem there's not a lot anyone else can really do but make educated guesses.
You can write your own equivalent of the Stack Length object and see how that compares. It's as simple as seeding the stack array with some unlikely to be put on stack constant and then checking how much of the stack remains seeded during / after execution. You can also check that a long variable / array after stack isn't being corrupted by stack overflow ...
Post Edited (hippy) : 9/25/2008 3:11:54 PM GMT
It is possible to walk the bytecode and build a graph of method calls and determine the worse case stack depth used from any point in a program including inter-object calls. And that should work in all cases except for recursion.
It's something I've been planning to add to my PropList but I need to get a round tuit.
The other is that the times that I display the stack length from the cog that I am getting the stack size of. Its always been the display code that used the most stack and if the display code wasn't in a loop I wouldn't see that and get teh stack size too small
********** MY FAULT *********
(Can you hear how I’m banging my head against the wall?)
As always the, the tougher the problem the more stupid the cause.
I went again through the code and realized that when I changed the stack size to the suggested value I didn’t change the second parameter, Longs, in the “Stack Length” Init method. After correcting this I’m getting consistent results.
How could I make such a stupid mistake.
Thank you all,
Enrique
In my case I’m getting a usage of 11, how much should I add to it?
Enrique
I spent ages trying to find an obscure bug in my debugger only to find out I had exceeded the stack, which of course, I had defined early in my coding before I thought about all the other bits I could add.
Anyone who wanted to specify a stack ( an @var or a function which returns an address ) could do so as they do now so entirely 100% backwards compatible, if through recursion it's not possible to auto-allocate a stack that can be reported as a compilation error.
How many "how big does the stack need to be ?" questions, how many stack too small problems and how much wasted memory from over-size stack guesses would that get rid of ? Nearly all of them I'd imagine.
Aren't we all sick of or hate trying to guess the size of stack required ? Don't we all ultimately just take a stab in the dark, make it 'large' or keep our fingers crossed ?