Stack is slow than heap?

N

Nephi Immortal

I always agree that stack is very effectively fast to push built-in
type variables into stack and pop them out of it between function
calls. Small stack size is very important. I have no idea how big it
can hold hundreds or thousands of variables.
It is possible to overflow the stack size if you use too many buffers
or small arrays. Hundreds or thousands of buffers or small arrays are
pushed into stack if you call 100 function calls before stack grows
bigger fast. Error assert message is triggered to report stack
overflow.
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?
After you write a function, do you prefer to store one buffer to hold
1,024 bytes or 4,096 bytes? Should 4,096 bytes be sufficient to hold
buffer or small array in stack? Every time, function is called and it
takes CPU time to push empty buffer or small array into stack, do
algorithm, and pop used buffer or small array out of stack prior
exiting function is always slow.
What option do you have? Do you prefer to create global variables to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

For example:

void foo( const char *dest )
{
char buffer[ 1024 ]; // pusb 1,024 bytes into stack
// char *buffer = g_buffer; // set pointer to buffer in global scope

char *pBuffer = buffer;
char *pDest = dest;

do
{
*pBuffer = *pDest;
++pBuffer;
++pDest;
}
while( *pDest != ‘\0’ );

*pBuffer = ‘\0’;

// Create more buffers or small arrays and copy
// them into one buffer
// Do algorithm

cout << pBuffer << endl;

// Pop all buffers and small arrays out of stack
// and exit function
}

Perhaps, you suggest to use heap in global scope.

// global scope
char *buffer = 0; // or you can use string class or vector class

int main()
{
buffer = new char[ 4096 ];

foo( buffer );

delete [] buffer;

// you can replace new / delete to string class or vector class
}

Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?
 
V

Victor Bazarov

[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.
After you write a function, do you prefer to store one buffer to hold
1,024 bytes or 4,096 bytes?

I prefer to store what my algorithm tells me to store.
Should 4,096 bytes be sufficient to hold
buffer or small array in stack?

Depends on the use of the buffer.
Every time, function is called and it
takes CPU time to push empty buffer or small array into stack, do
algorithm, and pop used buffer or small array out of stack prior
exiting function is always slow.
Huh?

What option do you have? Do you prefer to create global variables to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

Use anything available to you. If the size of the buffer is known at
the compile-time, AND it's small enough, you can declare it locally in
some function. It's *usually* as fast as, or faster than, dynamic
allocation of arrays. If the size of the buffer is *not* known until
run-time, you have a choice, use 'new[]/delete[]' and do it yourself or
use standard containers.
For example:
[..snip..]

Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?

Please re-phrase the question. I don't understand what it is you're
trying to learn about the stack (I presume you're talking about the
process' memory for objects with automatic storage duration).

V
 
E

Edek

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

the above is false
for example if
int f0(int x){return x-1;}
int f1(int x){return f0(x);}
int f2(int x){return f1(x);}

f2(3)
make grow the stack to number of function call
even if f2() is not recursive

but it is difficult to find such way to dispose
functions...

Two ways: inlining, that's one, but it might be limited in
depth, VC had some flags saying how many recursive calls to
inline.

Also C/C++ compilers do something called tail-call.
Tail-call replaces return-what-call-returns with
a jump (a machine goto). Obviously, there must be another return
somewhere eventually or an exception and this return
replaces the return-call->return; it is one of the
reasons why debugging optimised code or getting the
exception stack might not be very productive in C++.

In this way recursive algorithms can become iterative
or mixed in execution though.

Edek
 
B

BGB

[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.

and usually *much* smaller...

on Windows, the default size if 4MB.

I prefer to store what my algorithm tells me to store.


Depends on the use of the buffer.

yep.

sometimes 64 or 256 is more than sufficient...
and sometimes 4096 will still overflow.
it all depends on what one is doing, what data they are working with, ...


nothing really has to be "added" or "removed" from the stack, as it is
usually just a sliding pointer.


What option do you have? Do you prefer to create global variables to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

Use anything available to you. If the size of the buffer is known at the
compile-time, AND it's small enough, you can declare it locally in some
function. It's *usually* as fast as, or faster than, dynamic allocation
of arrays. If the size of the buffer is *not* known until run-time, you
have a choice, use 'new[]/delete[]' and do it yourself or use standard
containers.

yep, among other options.

unless one has a good reason though, global variables are generally bad
practice though, as:
depending on use, they may not mix well with the use of threads;
they impede modularity;
they reduce flexibility;
....

For example:
[..snip..]

Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?

Please re-phrase the question. I don't understand what it is you're
trying to learn about the stack (I presume you're talking about the
process' memory for objects with automatic storage duration).

I think the OP was asking how big the stack is...

but, it does not hold anywhere near that much.
 
N

Nick Keighley

Include your question in the body of your post

"Stack is slow than heap"

maybe. It all depends on the implementaion. I'd expect access time to
be very similar. Allocation/release is a little slower for heap
(dynamic memory) than stack (automatic memory).

        I always agree that stack is very effectively fast to push built-in
type variables

what about non-built in types? isn't any small type quick to push and
pop?
into stack and pop them out of it between function
calls.  Small stack size is very important.
why?

 I have no idea how big it
can hold hundreds or thousands of variables.

depends on the implementation (this is the answer to most of your
questions)
        It is possible to overflow the stack size if you use too many buffers
or small arrays.

or one enormous array. Genrally speaking if you've got a lot of stuff
use dynamic (new/delete or a container) rather than automatic memory.

 Error assert message is triggered to report stack overflow.

maybe. It depends on the implementation

        After you write a function, do you prefer to store one buffer to hold
1,024 bytes or 4,096 bytes?

I've never been given this option!. I'd choose the smaller number if
1024 bytes were enough for my function. Wouldn't it be a good idea to
pick the correct number?
 Should 4,096 bytes be sufficient to hold
buffer or small array in stack?

this is a nonsense question. What is the buffer for?
 Every time, function is called and it
takes CPU time

not much. It probably isn't proportional to the buffer size.
to push empty buffer or small array into stack, do
algorithm, and pop used buffer or small array out of stack prior
exiting function is always slow.

have you measured it?
        What option do you have?  Do you prefer to create global variables

no. Global data is hardly ever a good idea.
to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

how do you know your function is too slow? What is the buffer used
for? i/o?

        Please answer one question.  How big can stack hold up to 500
megabytes on 32 bits machine?

I don't understand. This doesn't parse.
 
N

Nephi Immortal

[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?
It is usually controlled by the settings of your linker.

and usually *much* smaller...

on Windows, the default size if 4MB.

I see. the size of stack 4 MB answers my question.
yep.

sometimes 64 or 256 is more than sufficient...
and sometimes 4096 will still overflow.
it all depends on what one is doing, what data they are working with, ...

Make sense.
 > Every time, function is called and it

nothing really has to be "added" or "removed" from the stack, as it is
usually just a sliding pointer.
Use anything available to you. If the size of the buffer is known at the
compile-time, AND it's small enough, you can declare it locally in some
function. It's *usually* as fast as, or faster than, dynamic allocation
of arrays. If the size of the buffer is *not* known until run-time, you
have a choice, use 'new[]/delete[]' and do it yourself or use standard
containers.

yep, among other options.

unless one has a good reason though, global variables are generally bad
practice though, as:
depending on use, they may not mix well with the use of threads;
they impede modularity;
they reduce flexibility;

Of course, global variable is bad idea if you choose to use thread.
If two or more threads are running at the same time while accessing
one global variable directly, why not create backup variable?

// global scope
char* pBuffer = 0;

void foo()
{
char* pTemp = pBuffer;

// do algorithm on second thread
pBuffer = pThread_Buffer2;

// do algorithm on third thread
pBuffer = pThread_Buffer3;

// do algorithm on fourth thread
pBuffer = pThread_Buffer4;

// restore buffer pointer prior exiting function
pBuffer = pTemp;
}

If I understand correctly, you want to create four threads and you
will need to create one copy of buffer to each thread. All threads
cannot share the same one buffer directly. Buffer class is a good
idea.

...
For example:
[..snip..]
Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?
Please re-phrase the question. I don't understand what it is you're
trying to learn about the stack (I presume you're talking about the
process' memory for objects with automatic storage duration).

I think the OP was asking how big the stack is...

but, it does not hold anywhere near that much.
 
N

Nephi Immortal

Include your question in the body of your post

"Stack is slow than heap"

maybe. It all depends on the implementaion. I'd expect access time to
be very similar. Allocation/release is a little slower for heap
(dynamic memory) than stack (automatic memory).

Heap is slow unless you allocate and deallocate heap many times.
Heap is pretty fast if you allocate one time prior reaching main
function and deallocate one time after exiting main function. If you
insist, you have to allocate and deallocate very often, you will
implement your own memory pool to speed up performance.
what about non-built in types? isn't any small type quick to push and
pop?


depends on the implementation (this is the answer to most of your
questions)


or one enormous array. Genrally speaking if you've got a lot of stuff
use dynamic (new/delete or a container) rather than automatic memory.



maybe. It depends on the implementation



I've never been given this option!. I'd choose the smaller number if
1024 bytes were enough for my function. Wouldn't it be a good idea to
pick the correct number?


this is a nonsense question. What is the buffer for?

If you have multiple buffers outside function, you will need to
create one temporary buffer inside function and copy all multiple
buffers into one buffer before one buffer outputs to the screen like
printf() or cout << … << endl;
I guess temporary buffer should hold sufficient 4,096 bytes or less.
 
F

Fred Zwarts \(KVI\)

"Nephi Immortal" wrote in message
Heap is slow unless you allocate and deallocate heap many times.
Heap is pretty fast if you allocate one time prior reaching main
function and deallocate one time after exiting main function. If you
insist, you have to allocate and deallocate very often, you will
implement your own memory pool to speed up performance.

Heap and stack are usually accessing the same memory. So access times are
not different. Only allocation/release times are different.
Allocating/releasing stack is usually somewhat faster.
...

If you have multiple buffers outside function, you will need to
create one temporary buffer inside function and copy all multiple
buffers into one buffer before one buffer outputs to the screen like
printf() or cout << … << endl;
I guess temporary buffer should hold sufficient 4,096 bytes or less.

It depends on what you want to do. If you want to output one line of text,
then a buffer of about 100 characters may be sufficient. If you want to
refresh a whole screen in one go, then it depends on the screen resolution
and the possible values of one cell. A screen with a resolution of about 200
x 100 and about 200 possible values per cell will need already a buffer of
at about 20000 bytes.
 
N

Nephi Immortal

"Nephi Immortal" <[email protected]> ha scritto nel messaggio

Of course, global variable is bad idea if you choose to use thread.
If two or more threads are running at the same time while accessing
one global variable directly, why not create backup variable?

// global scope
char* pBuffer = 0;

void foo()
{
char* pTemp = pBuffer;

// do algorithm on second thread
pBuffer = pThread_Buffer2;

// do algorithm on third thread
pBuffer = pThread_Buffer3;

// do algorithm on fourth thread
pBuffer = pThread_Buffer4;

// restore buffer pointer prior exiting function
pBuffer = pTemp;

}

If I understand correctly, you want to create four threads and you
will need to create one copy of buffer to each thread.  All threads
cannot share the same one buffer directly.  Buffer class is a good
idea.

#this is io_x
#yes that it is possible
#but in windows it is possible too
#many tread have in common one buffer
#provide that each thread has one lock on write-read on that buffer
#if i remember well. but i'm not sure of that or for the follow:
#the same for one file
#many thread can have in common one file if it is right lock
#on write or on read to each thread...

Do main function only have ONE process and ONE thread at this time
unless you tell operating system to create multiple threads?
 
C

Cholo Lennon

[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.

and usually *much* smaller...

on Windows, the default size if 4MB.

Correction: The default size, at least in Win32/VC++, is 1 MB, not 4 MB.
I prefer to store what my algorithm tells me to store.


Depends on the use of the buffer.

yep.

sometimes 64 or 256 is more than sufficient...
and sometimes 4096 will still overflow.
it all depends on what one is doing, what data they are working with, ...


nothing really has to be "added" or "removed" from the stack, as it is
usually just a sliding pointer.


What option do you have? Do you prefer to create global variables to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

Use anything available to you. If the size of the buffer is known at the
compile-time, AND it's small enough, you can declare it locally in some
function. It's *usually* as fast as, or faster than, dynamic allocation
of arrays. If the size of the buffer is *not* known until run-time, you
have a choice, use 'new[]/delete[]' and do it yourself or use standard
containers.

yep, among other options.

unless one has a good reason though, global variables are generally bad
practice though, as:
depending on use, they may not mix well with the use of threads;
they impede modularity;
they reduce flexibility;
...

For example:
[..snip..]

Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?

Please re-phrase the question. I don't understand what it is you're
trying to learn about the stack (I presume you're talking about the
process' memory for objects with automatic storage duration).

I think the OP was asking how big the stack is...

but, it does not hold anywhere near that much.
 
B

BGB

On 11/7/2011 11:27 AM, Nephi Immortal wrote:
[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.

and usually *much* smaller...

on Windows, the default size if 4MB.

Correction: The default size, at least in Win32/VC++, is 1 MB, not 4 MB.

funny, I had thought I had read before that it was 4MB.

however, at least going by the PE/COFF header values, it appears you are
correct...

hmm...

either way though, it aint no 512MB or 1GB...

After you write a function, do you prefer to store one buffer to hold
1,024 bytes or 4,096 bytes?

I prefer to store what my algorithm tells me to store.

Should 4,096 bytes be sufficient to hold
buffer or small array in stack?

Depends on the use of the buffer.

yep.

sometimes 64 or 256 is more than sufficient...
and sometimes 4096 will still overflow.
it all depends on what one is doing, what data they are working with, ...

Every time, function is called and it
takes CPU time to push empty buffer or small array into stack, do
algorithm, and pop used buffer or small array out of stack prior
exiting function is always slow.

Huh?

nothing really has to be "added" or "removed" from the stack, as it is
usually just a sliding pointer.


What option do you have? Do you prefer to create global variables to
hold buffer or small array into heap through reference or pointers
between function calls can be faster?

Use anything available to you. If the size of the buffer is known at the
compile-time, AND it's small enough, you can declare it locally in some
function. It's *usually* as fast as, or faster than, dynamic allocation
of arrays. If the size of the buffer is *not* known until run-time, you
have a choice, use 'new[]/delete[]' and do it yourself or use standard
containers.

yep, among other options.

unless one has a good reason though, global variables are generally bad
practice though, as:
depending on use, they may not mix well with the use of threads;
they impede modularity;
they reduce flexibility;
...

For example:
[..snip..]

Please answer one question. How big can stack hold up to 500
megabytes on 32 bits machine?

Please re-phrase the question. I don't understand what it is you're
trying to learn about the stack (I presume you're talking about the
process' memory for objects with automatic storage duration).

I think the OP was asking how big the stack is...

but, it does not hold anywhere near that much.
 
N

Nick Keighley

        Heap is slow unless you allocate and deallocate heap manytimes.
what?

Heap is pretty fast if you allocate one time prior reaching main
function and deallocate one time after exiting main function.  If you
insist, you have to allocate and deallocate very often, you will
implement your own memory pool to speed up performance.

only if you have MEASURED the performance of your program, shown it
does not meet its documented perfaormance criteria and also MEASURED
the performance of the modified program and shown it is better.


I'd choose the number that was correct for the program.
        If you have multiple buffers outside function, you will need to
create one temporary buffer inside function and copy all multiple
buffers into one buffer before one buffer outputs to the screen like
printf() or cout << … << endl;

why? I don't see why you have to do this.

cout << buffer1 << buffer2 << buffern < "\n";
        I guess temporary buffer should hold sufficient 4,096 bytes or less.

why? I don't know what a "temporary buffer" is. If it's holding a
large JPEG then 4096 bytes is way too small.

<snip>
 
W

Werner


I think he might have meant "when you de-/ allocate many times".
only if you have MEASURED the performance of your program, shown it
does not meet its documented perfaormance criteria and also MEASURED
the performance of the modified program and shown it is better.

Measure or not, the fact remains that using memory management schemes
that make use of pre-allocated memory (on heap) [can] give a program
more deterministic behaviour in terms of allocation time. One can
rely on getting/returning memory in constant time. The heap caters
for too many different cases (not specialized enough) and using it
does not guarantee consistent behaviour over a range of scenarios.
Therefore - what exactly are you going to measure? If you do need
deterministic behaviour, the heap is not good enough. Most of the
time it is, though.

IM(h)O the behaviour of the stack wrt. allocation/deallocation time
is more deterministic (my impression). For me that would be an
interesting debate.

Regards,

Werner
 
J

Jorgen Grahn

On 11/7/2011 9:47 AM, Victor Bazarov wrote:
On 11/7/2011 11:27 AM, Nephi Immortal wrote:
[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.


and usually *much* smaller...

on Windows, the default size if 4MB.

Correction: The default size, at least in Win32/VC++, is 1 MB, not 4 MB.

funny, I had thought I had read before that it was 4MB.

however, at least going by the PE/COFF header values, it appears you are
correct...

hmm...

either way though, it aint no 512MB or 1GB...

And more importantly, no "a handful of kilobytes" which used to be the
norm a couple of decades ago (and still is on some embedded systems).

Personally, and for "normal" C++ code, I'd start worrying about my
design if I found myself needing more than 100KB or so of stack.
That doesn't seem quite normal.

/Jorgen
 
D

Dombo

Op 09-Nov-11 12:03, Werner schreef:

I think he might have meant "when you de-/ allocate many times".
only if you have MEASURED the performance of your program, shown it
does not meet its documented perfaormance criteria and also MEASURED
the performance of the modified program and shown it is better.

Measure or not, the fact remains that using memory management schemes
that make use of pre-allocated memory (on heap) [can] give a program
more deterministic behaviour in terms of allocation time. One can
rely on getting/returning memory in constant time. The heap caters
for too many different cases (not specialized enough) and using it
does not guarantee consistent behaviour over a range of scenarios.
Therefore - what exactly are you going to measure? If you do need
deterministic behaviour, the heap is not good enough. Most of the
time it is, though.

IM(h)O the behaviour of the stack wrt. allocation/deallocation time
is more deterministic (my impression). For me that would be an
interesting debate.

That is what I would expect. The compiler can figure out where a object
should go relative to the stack pointer during compile time, all
compilers of which I have studied the assembly output do this. At
runtime accessing an object on the stack is simply a matter of applying
a fixed offset to the stack pointer.

Allocating memory on the heap is typically slower because in this case
the address where the object should must be determined at runtime. In
most cases the time it takes to allocate memory on the heap is not
deterministic.

Once the memory is allocated I don't see any particular reason why
accessing an object on the stack should slower or faster than an object
on the heap on a typical architecture.
 
B

BGB

BGB said:
On 07/11/2011 19:28, BGB wrote:
On 11/7/2011 9:47 AM, Victor Bazarov wrote:
On 11/7/2011 11:27 AM, Nephi Immortal wrote:
[..]
How big can stack hold on 32 bits machine? Should it hold between
500 megabytes and 1 gigabytes of memory?

It is usually controlled by the settings of your linker.


and usually *much* smaller...

on Windows, the default size if 4MB.


Correction: The default size, at least in Win32/VC++, is 1 MB, not 4
MB.

funny, I had thought I had read before that it was 4MB.

IIRC it is 1M in 32-bit and 4M for 64-bit apps. So you are both right ;-)

that could be it...


I have developed both 32 and 64 bit apps, and a lot of when I was
looking into this stuff was when building 64-bit stuff.

I eventually returned to compiling for 32-bits though mostly because I
am still using some 32-bit systems, but in the future may go 64-bits only.
 
R

Richard Damon

Once the memory is allocated I don't see any particular reason why
accessing an object on the stack should slower or faster than an object
on the heap on a typical architecture.

Actually the heap may be slightly slower as the stack variable is at an
addressed based on a value that is already sitting in the registers (the
stack pointer), while to get to the heap variable, the pointer to it may
need to be loaded from either a stack based or global variable.
 
J

Juha Nieminen

Jorgen Grahn said:
Personally, and for "normal" C++ code, I'd start worrying about my
design if I found myself needing more than 100KB or so of stack.
That doesn't seem quite normal.

You clearly don't use many recursive algorithms.
 
J

Jorgen Grahn

You clearly don't use many recursive algorithms.

Does anybody?

I suppose I wouldn't mind one if there's a clearly defined max
recursion depth though.

/Jorgen
 
J

Juha Nieminen

Jorgen Grahn said:
Does anybody?

You probably use them all the time, even without realizing. (Quicksort
is a recursive algorithm, and std::sort() usually uses introspective sort,
which uses quicksort as one of its steps.)

I use them from time to time when I need to implement algorithms which
are very recursive in nature. Often implementing them non-recursively
makes the implementation significantly more complicated (and usually
longer) than the recursive version.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top