ba@m2-net.UUCP (Bill Allen) (09/29/89)
"Up your stack..." What causes certain prgs to work just fine in 4K of stack (or less) while others need 10K? I've seen several that require 20K, 30K, 40K. Can other programming techniques be used to prevent this? The record is 60K and a "if it crashes, increase it more". Is this "poor" programming or are there legitimate needs for unavoidable minimum 60,000+ byte stack. -- --------------------------------------------------------- Reply-To: ba@m2-net.UUCP (Bill Allen Beogelein) M-NET, Ann Arbor, MI or call Sharewarer's BBS at 313-473-2020 24hrs, PCP thru MIDET, 100% Amiga ---------------------------------------------------------
cmcmanis%pepper@Sun.COM (Chuck McManis) (09/30/89)
In article <3944@m2-net.UUCP> ba@m-net.UUCP (Bill Allen) writes: >What causes certain prgs to work just fine in 4K of stack >(or less) while others need 10K? I've seen several that >require 20K, 30K, 40K. Depends on what they put there. Some programs, like anything compiled with Lattice 5.x will adjust the stack when they start up, others just take what you give them. > Can other programming techniques be used to prevent this? Usually they can. A really common programmer error is to have a program that does something like : main() { unsigned char image1[640][200], image2[640][200]; ... } Or something equally innocent in appearance. What in fact happens is that these two arrays, being local to the main function, get allocated on the stack and that blow 256K of memory. Or even more common is a recursive function that has some fairly large number of local variables. Anyway those all eat up stack. > Is this "poor" programming or are there legitimate needs for > unavoidable minimum 60,000+ byte stack. There are legitimate reasons why you might need lots of stack space but I can't think of any off the top of my head :-). --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you. "If I were driving a Macintosh, I'd have to stop before I could turn the wheel."
daveh@cbmvax.UUCP (Dave Haynie) (10/02/89)
in article <3944@m2-net.UUCP>, ba@m2-net.UUCP (Bill Allen) says: > "Up your stack..." > What causes certain prgs to work just fine in 4K of stack > (or less) while others need 10K? I've seen several that > require 20K, 30K, 40K. Can other programming techniques be > used to prevent this? The difference usually amounts to something like this: // Stack Wasting Example void thing1(void) { char temporary[200000]; // Do the interesting stuff } // Doesn't waste stack void thing2(void) { char *temporary = malloc(200000); // Do the interesting stuff free(temporary); } // Doesn't waste stack void thing3(void) { static char temporary[200000]; // Do the interesting stuff } These functions would each do the same thing, only the first allocates it's temporary buffer on the stack, and would take 200,000 bytes of stack memory to run, the second allocates it's temporary buffer from the memory pool upon entry to the function, and returns that memory upon exit. The third function allocates that temporary statically, for the life of the program. That doesn't take stack memory, but it might take more system memory at any given time than absolutely necessary, and of course will cause trouble if the programmer expected a new "temporary" to be allocated upon each entry to the function (often the case if you're using recursion). The programmer should be sentitive to this. Small allocations on the stack are certainly no problem, but large ones are. In most, though not every case, programs that use lots of stack could be using less with more clever programming. > Is this "poor" programming or are there legitimate needs for unavoidable > minimum 60,000+ byte stack. Chances are, that programmer never even thought about how much stack was being used. > --------------------------------------------------------- > Reply-To: ba@m2-net.UUCP (Bill Allen Beogelein) M-NET, Ann Arbor, MI > or call Sharewarer's BBS at 313-473-2020 24hrs, PCP thru MIDET, 100% Amiga > --------------------------------------------------------- -- Dave Haynie Commodore-Amiga (Systems Engineering) "The Crew That Never Rests" {uunet|pyramid|rutgers}!cbmvax!daveh PLINK: hazy BIX: hazy Too much of everything is just enough
UH2@PSUVM.BITNET (Lee Sailer) (10/03/89)
Would it be useful for Amiga compilers to at least partially detect things like main() { int x[200000]; ... } and WARN the user that this will use up a lot of stack?
sjk@ut-emx.UUCP (bob) (10/03/89)
Dave Haynie writes: > in article <3944@m2-net.UUCP>, ba@m2-net.UUCP (Bill Allen) says: > > > What causes certain prgs to work just fine in 4K of stack > (or less) while others need 10K? I've seen several that > require 20K, 30K, 40K. Can other programming techniques be > used to prevent this? > The difference usually amounts to something like this: > [exampes deleted] Dave, you're probably right, the average programmer probably does not know how much stack he is using, or even wonder, perhaps. So what constructs are there that require stack use? I am a novice C programmer and while I am capable of writing some relatively complex code, I don't yet know enough about the internal operations to know what structures use how much stack and why. Where can I learn this kind of stuff? I think it would prove quite useful. I already have a few programs that need stacks ~50K and have no idea why; it would be great to be able to change this! Thanks, Scot sjk@astro.as.utexas.edu Bdah!- M
new@udel.edu (Darren New) (10/03/89)
As far as I know, in Lattice C only automatic variables live on the stack. If there are other things on the stack, you would have to change the run-time support or maybe even the compiler in order to eliminate them. Keeping large buffers off the stack is the easiest way to cut stack usage. However, it usually isn't worth it unless you can cut the stack size down to where the program will run with the default stack size (4K, I think), as the user will have to set the stack anyway. Usually the run-time routines and the OS and libraries and ... will use some stack too, but I don't remember how much; usually a few hundred bytes is enuf for well-designed libraries. The secret is to calculate and KNOW how much stack you need. Just look at the nesting tree for your program and add up all the automatic space used (plus alignment and such) and find the branch that uses the most stack space. That (plus a few K) is how big to make your stack. For recursive functions, you will need to add some for the automatic variables of the recursive function. But basically, in C, automatic variables are what use stack space. -- Darren
usenet@cps3xx.UUCP (Usenet file owner) (10/04/89)
In article <620@nigel.udel.EDU> new@udel.edu (Darren New) writes: >way to cut stack usage. However, it usually isn't >worth it unless you can cut the stack size >down to where the program will run with the default >stack size (4K, I think), as the user will have to >set the stack anyway. Usually the run-time routines and >the OS and libraries and ... will use some stack too, >but I don't remember how much; usually a few hundred >bytes is enuf for well-designed libraries. The secret is >to calculate and KNOW how much stack you need. Probly the best way is for the CLI to set the stack like the Workbench does..... What I do for my own programs is have them set the stack themselves. I use the technique by Werner Guenther (not sure about spelling) to detach from the CLI by splitting the first segment away from the rest, then do a CreateProc and have it set the stack size this way. How do I know how much stack? (This works well for non-recursive, or limited recursion) In the startup code (in the slipt off part) the first thing it does is clear the stack to a constant (non-zero). It then calls _main, and then counts the number of bytes on the stack still containing that pattern, and prints out info about stack usage. This is for development only. Once the program is 'finished', then remove or disable the stack counting stuff. ( i simply use a cmd line arg "debug" to turn it on when I want). For this to work proerly the program must be taken trough all its functions, or at least the deepest (procedural wise) functions. REAL NAME: Joe Porkka porkka@frith.egr.msu.edu
8610681@maven.u.washington.edu (10/04/89)
In article <19086@ut-emx.UUCP>, sjk@ut-emx.UUCP (bob) writes: > Dave Haynie writes: >> in article <3944@m2-net.UUCP>, ba@m2-net.UUCP (Bill Allen) says: >> >> > > What causes certain prgs to work just fine in 4K of stack > > (or less) while others need 10K? I've seen several that > > require 20K, 30K, 40K. Can other programming techniques be > > used to prevent this? > >> The difference usually amounts to something like this: >> [exampes deleted] > > Dave, you're probably right, the average programmer probably does > not know how much stack he is using, or even wonder, perhaps. So > what constructs are there that require stack use? I am a novice > C programmer and while I am capable of writing some relatively > complex code, I don't yet know enough about the internal operations > to know what structures use how much stack and why. While it's certainly good for programmers to have knowledge of the specifics of a machine, and understanding stack usage is a legitimate exercise, it does seem rather silly to force applications to be written quite differently on one machine than another. If I want to write code like: int routine() { int big_space_waster[100000]; { whatever} } I should be able to. Now, it seems that on a non-virtual memory machine (or any machine with a fixed stack space), that the compiler ought to be able to optimize such large requests for local stack into a malloc() on entry and free() on return itself. I should not be have to concerned with such implementation details. Perhaps a flag on the compilation line would dictate whether this behaviour was appropriate and what size of memory to start doing this at. Cheers, Joe Meadows joe@fhcrcvax.bitnet
fnf@estinc.UUCP (Fred Fish) (10/11/89)
In article <4837@cps3xx.UUCP> porkka@frith.UUCP (Joe Porkka) writes: >What I do for my own programs is have them set the stack themselves. >I use the technique by Werner Guenther (not sure about spelling) to >detach from the CLI by splitting the first segment away from the >rest, then do a CreateProc and have it set the >stack size this way. I just had a need to set my own stack also, in a program that was being run from another program via Execute(). It turns out that the child process was getting a 4K stack no matter what stack the parent process had. Following a tip from John Toebes (thanks John!) I changed the call to the Execute() command to look something like: Execute ("stack 40000\nmyprogram", ...) which worked just fine. -Fred -- # Fred Fish, 1835 E. Belmont Drive, Tempe, AZ 85284, USA # 1-602-491-0048 asuvax!{nud,mcdphx}!estinc!fnf
walker@sas.UUCP (Doug Walker) (10/13/89)
In article <125522@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes: >In article <3944@m2-net.UUCP> ba@m-net.UUCP (Bill Allen) writes: >Depends on what they put there. Some programs, like anything compiled >with Lattice 5.x will adjust the stack when they start up, others just >take what you give them. Not quite true, Chuck. If you link with cres.o or cback.o it adjusts your stack for you; if you link with the normal c.o it doesn't. However, Lattice does CHECK your stack size for you unless you specify -v; if your program overruns the stack, a requester will pop up. > >> Can other programming techniques be used to prevent this? > Sure. Allocate everything with AllocMem, or declare variables static or extern. The following items get put on the stack: 1) Local variables (autos) 2) Function parameters 3) Function return values 4) Register saves 5) Temporary values that spill out of registers (generally a VERY small number, less than 20 bytes). The deeper your nesting level, the more stack you will need. Thus, recursive programs can be a problem. I once had an application using N-way trees (each node can have 1-n children) and I walked the tree using callmyself(rightsibling); callmyself(leftmostson); processmyself(); I thought this worked great! Very little code, really efficient, right? WRONG! The trees I was dealing with were perhaps 4-5 levels deep, but very broad. The callmyself(rightsibling) was pushing itself onto the stack once for each sibling at a given level. I very quickly discovered that stack size IS a problem! I changed the code to for(current=me; current != NULL; current=current->rightsibling) callmyself(current->leftmostson); processmyself(); This relatively small code change saved THOUSANDS OF BYTES of stack, while doing exactly the same thing as the previous code. >> Is this "poor" programming or are there legitimate needs for >> unavoidable minimum 60,000+ byte stack. > >There are legitimate reasons why you might need lots of stack space >but I can't think of any off the top of my head :-). The only reason would be very deep, legitimate recursion. (By 'legitimate' I mean 'unavoidable by simple tricks like above'). Cases that require this kind of recursion are extremely rare. 99% of the time the 60K stack requirement is due to the programmer allocating large auto arrays. Remember, folks, any arrays you allocate in main() remain on the stack the whole time you are running; if you can do your parsing in a subroutine instead of main(), for example, all the auto variables you used during parsing will go away when you return. > >--Chuck McManis --Doug Walker