.data
Dtotal REAL8 4294967296.0
Dfree REAL8 10000.0
NU8 REAL8 8.0
NU100 REAL8 100.0
NU1024 REAL8 1024.0
.code

getallspaces Proc,pcdrivePTR:DWORD,ppTOTAL:DWORD,pFREE:DWORD,pUSED:DWORD,pTOTALBITS:DWORD,pTOTALGB:DWORD,
pTOTAL8GB:DWORD,pFREEBITS:DWORD,pFREEGB:DWORD,pFREE8GB:DWORD,pUSEDBITS:DWORD,pUSED8GB:DWORD,pUSEDGB:DWORD,
pFREEPERCENT:DWORD,pUSEDPERCENT:DWORD


Local LdTotaltemp2:REAL8
Local LdTotaltemp3:REAL8
Local LdTotaltemp4:REAL8
Local LdTotaltemp5:REAL8
Local LdTotaltemp1:REAL8
Local Dpptotal:QWORD
Local Dppfree:QWORD
Invoke GetDiskFreeSpaceEx, pcdrivePTR, Addr Dppfree, Addr Dpptotal,NULL

fild Dpptotal ;convert from init to dec ;
fstp LdTotaltemp2 ; store into the double ;
fild Dppfree;convert from init to dec ;
fstp LdTotaltemp1 ; store into the double ;
mov eax, ppTOTAL ;load into regester ;
fld LdTotaltemp2 ; load total ;
fstp QWORD PTR [eax] ; store into imput ;
mov eax, pFREE ;load into regester ;
fld LdTotaltemp1 ;load free ;
fstp QWORD PTR [eax]; store into imput ;
mov eax, pUSED ;load into regester ;
fld LdTotaltemp2 ; load total on #1 ;
fld LdTotaltemp1 ; load free on #2 ;
fsub ; sub #2 from #1 ;
fstp QWORD PTR [eax] ; store in imput ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, pTOTALBITS ;8x bit total
fld LdTotaltemp2 ;
fld NU8
fmul
fstp QWORD PTR [eax]

fld QWORD PTR [eax]
mov eax, pTOTAL8GB
fld NU1024
fdiv
fstp LdTotaltemp3
fld LdTotaltemp3
fld NU1024
fdiv
fstp LdTotaltemp3
fld LdTotaltemp3
fld NU1024
fdiv
fstp QWORD PTR [eax]
fld QWORD PTR [eax]
fld NU8
fdiv
mov eax, pTOTALGB
fstp QWORD PTR [eax]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fild Dppfree;convert from init to dec ;
fstp LdTotaltemp1 ; store into the double ;

mov eax, pFREEBITS ;8x bit total
fld LdTotaltemp1 ;
fld NU8
fmul
fstp QWORD PTR [eax]

fld QWORD PTR [eax]
mov eax, pFREE8GB
fld NU1024
fdiv
fstp LdTotaltemp4
fld LdTotaltemp4
fld NU1024
fdiv
fstp LdTotaltemp4
fld LdTotaltemp4
fld NU1024
fdiv
fstp QWORD PTR [eax]

fld QWORD PTR [eax]
fld NU8
fdiv
mov eax, pFREEGB
fstp QWORD PTR [eax]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov eax, pUSED
fld QWORD PTR [eax]
fstp LdTotaltemp5

mov eax, pUSEDBITS ;8x bit total
fld LdTotaltemp5 ;
fld NU8
fmul
fstp QWORD PTR [eax]

fld QWORD PTR [eax]
mov eax, pUSED8GB
fld NU1024
fdiv
fstp LdTotaltemp4
fld LdTotaltemp4
fld NU1024
fdiv
fstp LdTotaltemp4
fld LdTotaltemp4
fld NU1024
fdiv
fstp QWORD PTR [eax]

fld QWORD PTR [eax]
fld NU8
fdiv
mov eax, pUSEDGB
fstp QWORD PTR [eax]
;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, pFREE
fld QWORD PTR [eax]
mov eax, pUSED
fld QWORD PTR [eax]
fdiv
mov eax, pFREEPERCENT
fstp QWORD PTR [eax]
fld QWORD PTR [eax]
fld NU100
fmul
fstp QWORD PTR [eax]

mov eax, ppTOTAL
fld QWORD PTR [eax]
mov eax, pUSED
fld QWORD PTR [eax]
fdivr
mov eax, pUSEDPERCENT
fstp QWORD PTR [eax]
fld QWORD PTR [eax]
fld NU100
fmul
fstp QWORD PTR [eax]

mov eax,1; put 1 into return(true)
ret ; clean stack and return
getallspaces EndP
Posted on 2002-04-17 20:36:06 by Qages
There is PLENTY of room for improvement here, I tried at work just now, but I kept getting lost (turning from proper work to this & back was very confusing :( ).

I will look at it properly tonight, but first off you can save so much time & space using fst rather than fstp/fld the same data again. Why take data off the stack, then put it back on again?

Mirno
Posted on 2002-04-18 05:29:15 by Mirno
I think, that here it is better to use integer arithmetic. It is necessary to replace divisions on shifts.
Posted on 2002-04-18 14:06:14 by Nexo
How often is this going to be called, and is the overhead of your code
noticeable compared to the etDiskFreeSpaceEx call?
Posted on 2002-04-18 14:45:46 by f0dder
change



mov eax,1; put 1 into return(true)


to



xor eax, eax
inc eax


:grin: :stupid:
Posted on 2002-04-18 14:58:40 by bazik
it will prob be called every 250ms, defalut to 500ms, i dont know how fast it takes to execute it, and how would i use fst???

hmm seems to execute this code very fast, turns up as 0 ms in asm, even in vb when calling gettickcount, i need a more pricise mesurement, any api for this???
Posted on 2002-04-18 15:54:21 by Qages
What I'm trying to say is... this code doesn't really look like anything
speedcritical, so it's really a waste optimizing it. Of course optimizing
can be fun, and you can learn something even from optimizing this,
but there's better areas to optimize :).

There's roughly 112 instructions between the API call and the ret. Let's
just for fun assume that each instruction takes 100 clock cycles, this
would total in 11200 cycles for the code (should be quite less in practice ;)).
Even a lowly 166mhz has ~166000000 cycles/second, so it would be able to
execute your code roughly 14800 times per second. These figures should of
course be taken with a grain of salt, as there's a LOT of stuff going on
in a multitasking operating system, processors aren't totally straightforward,
I haven't slept quite enough last night (et cetera). Point is, your code
should be quite fast enough.

I wonder how many cycles the API call will take. I guess it involves some
ioctls which involve kernel transitions which are quite expensive. Wouldn't
be surprised if it takes quite an amount of cycles more than your calc code.
Again, doesn't really matter for this code.

So, what's the point of this post? Not to keep you from optimizing - but to
remind you of "the bigger picture". It's easy to get lost and want to optimize
every little piece of your programs and possibly end up never getting any
work done. Imo, it's about just as important knowing what to spend your time
on and what to "get done" as it is to be good at squeezing clock cycles.
Posted on 2002-04-18 17:05:37 by f0dder
Let's not qeustion in this section if speed is matter, please.
It's section for training of creation effective code. Even assuming that there might be sence in your words from general point of view, disscussion of speed problem in given example is one good material to exchange ideas and train your brain.
If we every time when we need to learn of implementing algo we
disscuss if we need to do it in the first place while here is some API we would never learn to make algos.
This section for creation and understanding, that all I have to say.
Posted on 2002-04-18 17:40:45 by The Svin
I go with Alex here, we have an algo section so that people can tweak or improve algorithms for whatever use they may have for it. f0dder has a good point that some code may not be worth the effort in terms of the bigger picture but if the author want it faster for some reason, I guess they have made their decisions about what matters in the bigger picture and need the extra speed.

Regards,

hutch@movsd.com
Posted on 2002-04-19 02:28:08 by hutch--
Qages fst is a floating point store, fstp is store and pop.

fst X <- stores ST(0) in X, ST(0) stays the same.
fstp x <- stores ST(0) in X, but ST(0) is removed from the floating point stack.

By not doing the pop, you don't have to reload it again!

So you can replace:


fld QWORD PTR [eax]
mov eax, pTOTAL8GB
fld NU1024
fdiv
fstp LdTotaltemp3
fld LdTotaltemp3
fld NU1024
fdiv
fstp LdTotaltemp3
fld LdTotaltemp3
fld NU1024
fdiv
fstp QWORD PTR [eax]
fld QWORD PTR [eax]
fld NU8
fdiv
mov eax, pTOTALGB
fstp QWORD PTR [eax]


with:


fld QWORD PTR [eax]
mov eax, pTOTAL8GB
fld NU1024
fdiv
fld NU1024
fdiv
fld NU1024
fdiv
fst QWORD PTR [eax]
fld NU8
fdiv
mov eax, pTOTALGB
fstp QWORD PTR [eax]

And they are identical.

This should give a pretty big saving in both speed and code size

Mirno

Mirno
Posted on 2002-04-19 03:30:01 by Mirno
Did I say he shouldn't optimize it? No. I just said look at the bigger
picture. Why? Because, judging by previous posts, Qages is a beginner
(nothing bad in that, we've all been there). If Svin would care to
re-read my post, it says:

Of course optimizing can be fun, and you can learn something
even from optimizing this
Posted on 2002-04-19 07:28:32 by f0dder
OK f0dder,
forget it :)
Posted on 2002-04-19 09:54:31 by The Svin


align 8
NU2p30r real8 1.0/1024/1024/1024
NU8m2p30r real8 1.0/8/1024/1024/1024
NU8 real4 8.0
NU100 real4 100.0

fild [Dppfree]
fild [Dpptotal]
fld st(1)
mov eax,[pFREE]
fst [real8 eax]
fld st(1)
mov eax,[pTOTAL]
fst [real8 eax]
fsubr
mov eax,[pUSED]
fstp [real8 eax]

macro Calc val,pFree,pTotal,pUsed
fld st(1)
fld st(1)
fld [val]
fmul st(2),st
fmul
mov eax,[pFree]
fst [real8 eax]
fxch st(1)
mov eax,[pTotal]
fst [real8 eax]
fsub
mov eax,[pUsed]
fstp [real8 eax]
endm
Calc NU8,pFREEBITS,pTOTALBITS,pUSEDBITS
Calc NU2p30r,pFREE8GB,pTOTAL8GB,pUSED8GB
Calc NU8m2p30r,pFREEGB,pTOTALGB,pUSEDGB

fdiv
fld [NU100]
fmul st(1),st
fsub st,st(1)
mov eax,[pUSEDPERCENT]
fstp [real8 eax]
mov eax,[pFREEPERCENT]
fstp [real8 eax]


Care of such quantities of parameters it is better to use one pointer on structure.
Posted on 2002-04-19 12:17:42 by Nexo
this is what i have so far



getallspaces Proc,pcdrivePTR:DWORD,ppTOTAL:DWORD,pFREE:DWORD,pUSED:DWORD,pTOTALBITS:DWORD,pTOTALGB:DWORD,
pTOTAL8GB:DWORD,pFREEBITS:DWORD,pFREEGB:DWORD,pFREE8GB:DWORD,pUSEDBITS:DWORD,pUSED8GB:DWORD,pUSEDGB:DWORD,
pFREEPERCENT:DWORD,pUSEDPERCENT:DWORD


Local LdTotaltemp2:REAL8
Local LdTotaltemp3:REAL8
Local LdTotaltemp4:REAL8
Local LdTotaltemp5:REAL8
Local LdTotaltemp1:REAL8
Local Dpptotal:QWORD
Local Dppfree:QWORD
Invoke GetDiskFreeSpaceEx, pcdrivePTR, Addr Dppfree, Addr Dpptotal,NULL
mov eax, ppTOTAL
mov ecx, pFREE
mov ebx, pUSED
fild Dpptotal
fst QWORD PTR [eax]
fstp LdTotaltemp2
fild Dppfree
fst QWORD PTR [ecx]
fst LdTotaltemp1
fld LdTotaltemp2
fsubr
fstp QWORD PTR [ebx]
fld LdTotaltemp2
fld NU8
fmul
mov eax, pTOTALBITS
fst QWORD PTR [eax]
fld NU1024
fdiv
fld NU1024
fdiv
fld NU1024
fdiv
mov eax, pTOTAL8GB
fst QWORD PTR [eax]
fld NU8
fdiv
mov eax, pTOTALGB
fstp QWORD PTR [eax]
fld LdTotaltemp1
fld NU8
fmul
mov eax, pFREEBITS
fst QWORD PTR [eax]
fld NU1024
fdiv
fld NU1024
fdiv
fld NU1024
fdiv
mov eax, pFREE8GB
fst QWORD PTR [eax]
fld NU8
fdiv
mov eax, pFREEGB
fstp QWORD PTR [eax]
fld QWORD PTR [ebx]
fld NU8
fmul
mov eax, pUSEDBITS
fst QWORD PTR [eax]
fld NU1024
fdiv
fld NU1024
fdiv
fld NU1024
fdiv
mov eax, pUSED8GB
fst QWORD PTR [eax]
fld NU8
fdiv
mov eax, pUSEDGB
fstp QWORD PTR [eax]
fld QWORD PTR [ecx]
fld QWORD PTR [ebx]
fdiv
mov eax, pFREEPERCENT
fld NU100
fmul
fstp QWORD PTR [eax]
mov eax, ppTOTAL
fld QWORD PTR [eax]
fld QWORD PTR [ebx]
fdivr
mov eax, pUSEDPERCENT
fld NU100
fmul
fstp QWORD PTR [eax]
xor eax, eax
inc eax
ret ; clean stack and return
getallspaces EndP
Posted on 2002-04-19 15:23:59 by Qages