| I'm not too familiar with the intricacies of NT stacks (and memory
allocation in general)... maybe someone else can shed some more light
on this.
There was some discussion earlier about this, either here or in the
developers' conference.
Yes, I believe the default stack _reserve_ is 1 MB, i.e. 1 MB virtual
memory is reserved (not necessarily committed). I'm not sure how much
the default commit is. As you've noted, you can set both using various
techniques.
I don't quite understand why you say the /STACK option and EDITBIN only
help to increase the stack size - you can decrease it also. Try
something like /STACK=1024,1024 and the memory usage should be much
lower than with the default.
Also note that the space reserved will be at least one page, i.e. 8k on
Alpha, 4k on Intel. Looks like in your example, each thread creates 3
pages. Don't know what the other two other are for, though...
|
| Thanks for your response,
>> I don't quite understand why you say the /STACK option and EDITBIN only
>> help to increase the stack size - you can decrease it also. Try
>> something like /STACK=1024,1024 and the memory usage should be much
>> lower than with the default.
There was no difference from /STACK=0,0 to /STACK=8192,8192. The VM size
increases 24K per thread. When I specify /STACK=8193,8193 each thread takes up
32K (ie. 1 more page)
Given below is a simple test program.
-Jayakumar
---------------------------------------------------------------------------
#include <windows.h>
#include "stdio.h"
void main(int argc, char **argv)
{
HANDLE nThr;
DWORD nId;
int i;
for (i=0; i<500; i++)
{
nThr = CreateThread(
NULL,
0,
(void *)threadFunc,
(void *)(i+1),
0,
&nId );
}
Sleep (100000);
}
void threadFunc (int i)
{
ShrinkStack ();/* presense or absence of this call makes no difference */
Sleep (100000);
}
/**
** function to shrink the stack to a bare minimum (from MSDN CD)
**/
void ShrinkStack (void)
{
MEMORY_BASIC_INFORMATION mbi;
PBYTE pbStackCrnt, pbStackBase, pb1stCommitPage, pbGuardPage;
SYSTEM_INFO si;
DWORD dwPageSize, dwProtectOld;
// Get the size of a page for this machine.
GetSystemInfo(&si);
dwPageSize = si.dwPageSize;
// Use _alloca() to get the current stack pointer
pbStackCrnt = (PBYTE) _alloca(1);
// Find the base of the stack's reserved region.
VirtualQuery(pbStackCrnt, &mbi, sizeof(mbi));
pbStackBase = (PBYTE) mbi.AllocationBase;
// Find the address of the first page of
// committed storage for the stack.
pb1stCommitPage = (PBYTE) mbi.BaseAddress;
// Find the address for the page beneath the
// current stack page. This page should have the
// PAGE_GUARD protection attribute flag.
pbGuardPage = pb1stCommitPage - dwPageSize;
// If the guard page overlaps the bottom-most page
// of the stack's region, we cannot shrink the stack.
if (pbStackBase == pbGuardPage)
return;
// Free the committed pages from the base
// of the stack region to the guard page.
VirtualFree(pbStackBase,
pbGuardPage - pbStackBase, MEM_DECOMMIT);
// Set the PAGE_GUARD flag on for the page
// beneath the current bottom of stack.
VirtualProtect(pbGuardPage, dwPageSize,
PAGE_READWRITE | PAGE_GUARD, &dwProtectOld);
}
|
|
Looks like the stack size can't be lowered than 24K on Alpha and 12K on Intel
-----------------------------------------------------------------------------
microsoft.public.vc.language news group
From: [email protected] (Felix Kasza [MVP])
Jay
You won't ever get below this limit. An NT stack, in its smallest
form, has a data page plus two guard pages; with 4K pages (Intel) or
8K pages (Alpha) this gives the results you noticed.
2000+ threads are not the way to handle large client counts anyway;
have you looked into thread pooling and I/O completion ports?
Cheers,
Felix.
|
| re .2, .3: Ok, I dodn't think of the guard pages... so that's three
pages in total.
�There was no difference from /STACK=0,0 to /STACK=8192,8192. The VM size
�increases 24K per thread.
Yeah, but as I said, the stack must be at least one page, that's why
0,0 and 8192,8192 make no difference (on Alpha).
|