News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

HeapAlloc error handling

Started by Don57, January 25, 2013, 02:13:51 AM

Previous topic - Next topic

dedndave

i don't see a big delay for probing into the guard page
but - you're right - why probe at all if you know how much you will be needing

hfheatherfox07

Quote from: MichaelW on February 03, 2013, 10:30:27 AM
Considering the amount of memory that most recent systems have installed, instead of probing the stack and incurring an exception-handling delay each time you probe into the guard page, why not just tell the linker to increase the stack size, setting the reserve and commit values to whatever you anticipate needing?


You means put your buffers in the .data section? And initialize them?
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

no - he means alter the stack allocation with a linker switch


i do measure a delay of about 2 clock cycles per 4 kb when probing 256 kb
that is the first time you probe only, of course
if i re-use that stack space, i get 20 cycles or something - the probe loop overhead

still, that is WAY faster than HeapAlloc
it suffers the same anomoly - but many more cycles
the first time i allocate and free 256 kb with HeapAlloc, i get something over 90000 cycles
after that, it is more like 50000 cycles

dedndave

for the benefit of newer coders, a little info about probing the stack...

QuoteBy default, Windows reserves 1 meg of virtual memory for the stack. No page of stack memory is actually allocated
(committed) until the page is accessed. This is demand-allocation. The page beyond the top of the stack is the guard
page. If this page is accessed, memory will be allocated for it, and the guard page moved downward by 4K (one page).
Thus, the stack can grow beyond the initial 1MB. Windows will not, however, let you grow the stack by accessing
discontiguous pages of memory. Going beyond the guard page causes an exception. Stack-probing code prevents this.

as quoted from osdev.org
http://wiki.osdev.org/How_kernel,_compiler,_and_C_library_work_together

you can probe the stack down, 4 kb at a time until you get the amount you want
or, you can adjust the commit amount on the linker command line
the later is most useful if you know how much will be needed in advance

hfheatherfox07

Thanks dedndave ,
I would love to learn more about it.....
Is there an example some where of how to do that? What are the switches ?
Is there a batch file for that ?
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

the linker switch is /STACK:reserve[,commit]

you can add that switch to the existing switches
so - just make a copy of the batch file you have and modify it

/STACK:1048576,16384
reserves 1 mb (the default under xp)
commits 16 kb of space
the behaviour varies a little on older operating systems

http://msdn.microsoft.com/en-us/library/8cxs58a6.aspx

hfheatherfox07

Quote from: dedndave on February 03, 2013, 02:14:56 PM
the linker switch is /STACK:reserve[,commit]

you can add that switch to the existing switches
so - just make a copy of the batch file you have and modify it

/STACK:1048576,16384
reserves 1 mb (the default under xp)
commits 16 kb of space
the behaviour varies a little on older operating systems

http://msdn.microsoft.com/en-us/library/8cxs58a6.aspx

Did I do It right ?
I used an example from Vortex
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

MichaelW

Quote from: dedndave on February 03, 2013, 11:04:27 AM
i don't see a big delay for probing into the guard page

I guess it depends on what the meaning of "big" is. On my P3 Windows 2000 system I get roughly 9000 cycles for each probe into the guard page.

;==============================================================================
include \masm32\include\masm32rt.inc
.686
;==============================================================================
.data
      count dq 0
.code
;==============================================================================
start:
;==============================================================================

    invoke GetCurrentProcess
    invoke SetProcessAffinityMask, eax, 1
    invoke Sleep, 5000

    ASSUME fs:NOTHING

    mov ebx, fs:[8]
    printf("%d\n", ebx )

    sub ebx, 4096
    mov DWORD PTR [ebx], 0

    mov ebx, fs:[8]
    printf("%d\n\n", ebx )

    xor eax, eax
    cpuid
    rdtsc
    push edx
    push eax

    mov ebx, fs:[8]
    sub ebx, 4096
    mov DWORD PTR [ebx], 0

    xor eax, eax
    cpuid
    rdtsc
    pop ecx
    sub eax, ecx
    pop ecx
    sbb edx, ecx
    mov DWORD PTR count, eax
    mov DWORD PTR count+4, edx
    printf("%I64d cycles\n\n", count)

    mov ebx, fs:[8]
    printf("%d\n\n", ebx )

    inkey
    exit
;==============================================================================
end start


1236992
1232896

9041 cycles

1228800


Well Microsoft, here's another nice mess you've gotten us into.

hfheatherfox07

I get the same error trying to compile this :

Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: main.asm
main.asm(19) : error A2008: syntax error : (
main.asm(25) : error A2008: syntax error : (
main.asm(46) : error A2008: syntax error : printf
main.asm(49) : error A2008: syntax error : (
_
Assembly Error
Press any key to continue . . .


Is it my linker ?
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

here is the test code i used, Michael
i used your timing macros and set the loop count to 1
i used the same 3 lines of code at startup as you have - with a 5 second delay
then, i made 5 passes on the test
the first pass shows the effect of probing
the remaining passes show the time for the probe loop overhead
it is advisable to run the test program several times to see realistic results
    ASSUME  FS:Nothing

    mov     eax,esp
    mov     edx,esp
    sub     eax,262144
    and     al,-16                ;16-aligned
    .repeat
        push    edx
        mov     esp,fs:[8]
    .until eax>=esp
    mov     esp,edx

    ASSUME  FS:ERROR


about 64 passes are made on the loop (256 kb / 4 kb)
so, you can take the first pass result
subtract out the loop overhead
and divide by 64 to get the effects of probing 1 page

MichaelW

QuoteIs it my linker ?

As qword pointed out in another thread, the problem is probably your version of MASM32. The printf and related macros require MASM32 version 11.
Well Microsoft, here's another nice mess you've gotten us into.

dedndave

oh - i can use printf - i just can't use parens inside of parens   :P
i typically use masm v 6.15, but i can switch to newer versions (not 11)

Heather
i looked at your linker switch batch file - it looks correct
you can observe the result using EditBin, or write code to see where the guard page is, relative to ESP
or, you can just access what you are supposed to have and see if an exception is generated   :biggrin:

jj2007

Quote from: dedndave on February 03, 2013, 11:18:39 PM
oh - i can use printf - i just can't use parens inside of parens   :P
i typically use masm v 6.15, but i can switch to newer versions (not 11)

I guess Michael meant Masm32 v11, not ML.exe 11.0 ;-)