News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Bin2Time, Converts binary value to hours:min:sec.000

Started by Tight_Coder_Ex, February 01, 2008, 10:54:48 PM

Previous topic - Next topic

ToutEnMasm


For a beginner,i will show GetTimeFormat that do all the job with NULL for required you don't want.
Then a messagebox can display the buffer,that all.

donkey

Quote from: ToutEnMasm on February 13, 2008, 01:54:56 PM

For a beginner,i will show GetTimeFormat that do all the job with NULL for required you don't want.
Then a messagebox can display the buffer,that all.

I also prefer GetTimeFormat as it will format the time for the proper locale but it does not accept the tick counter as input, it only accepts SYSTEMTIME structures, that is the only reason I didn't use it.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

NightWare

#17
updated donkey's approach... this time it's faster than lingo's algo on my core2, and it's also possible to optimise it a bit...
; diviser par 1000 (pour réduire la valeur à jours/heures/minutes/secondes)
mov eax,2199023256 ;; ) diviser par le nombre de millisecondes (1000) (vérifié de 0 à FFFFFFFFh)
mul ecx ;; )
shr edx,9 ;; )
mov ecx,edx ;; copier le résultat dans ecx

; obtenir le nombre de jours et d'heures
mov eax,2443359173 ;; ) diviser par le nombre d'heures (3600) (vérifié de 0 à 4320000)
mul edx ;; )
shr edx,11 ;; )
mov ebx,edx ;; placer le nombre d'heures et de jours dans ebx
mov eax,3600 ;; ) soustraire le nombre de jours et d'heures obtenus à notre sauvegarde
mul edx ;; )
sub ecx,eax ;; placer le nombre de minutes et de secondes dans ecx

; obtenir le nombre de jours
mov eax,178956971 ;; ) diviser par le nombre d'heures (24) (vérifié de 0 à 1200)
mul ebx ;; )
mov ElapsDays,edx ;; sauvegarder le nombre de jours
; obtenir le nombre d'heures
mov eax,24 ;; ) soustraire le nombre de jours obtenus à notre sauvegarde
mul edx ;; )
sub ebx,eax ;; )
mov ElapsHours,ebx ;; sauvegarder le nombre d'heures

; obtenir le nombre de minutes
mov eax,71582789 ;; ) diviser par le nombre de secondes (60) (vérifié de 0 à 3600)
mul ecx ;; )
mov ElapsMinutes,edx ;; sauvegarder le nombre de minutes
; obtenir le nombre de secondes
mov eax,60 ;; ) soustraire le nombre de minutes obtenues à notre sauvegarde
mul edx ;; )
sub ecx,eax ;; )
mov ElapsSeconds,ecx ;; sauvegarder le nombre de secondes


edit:  :wink

[attachment deleted by admin]

lingo

#18
"it's faster than lingo's algo on my core2"
Hence, you can post your speed testing prog to prove it (as Michael did).... :lol

Later:
Michael's code is correct but your "test prog" isn't
because you compare apples with bananas... :lol




NightWare

#19
 :bg i see, then this one... apples and bananas are really near...  :lol

edit : ok, i didn't see there was register preservation in your code, apologies  :(
edit2 : here it should be ok, but you push me to my limits man  :lol


[attachment deleted by admin]

donkey

#20
I took a bit of time to look at another way of attacking the problem and came up with this, using The Svin's magic divider, the AAM trick to convert 0-99, and a little trick for inserting the digits in a string, I came up with this...

DATA SECTION
szTimeFormat:
szDays DB "00 Days "
szHours DB "00:"
szMin DB "00:"
szSec DB "00."
szFrac DB 0,0,0,0,0,0

CODE SECTION
converttime:
invoke GetTickCount

mov esi,eax

// Days
mov edx, 3335999724
mul edx
shr edx, 26

mov eax,edx
aam
add eax,3030h
bswap eax
shr eax,16
mov [szDays],ax

// Hours
mov eax,86400000
mul edx
sub esi,eax
mov eax,esi

mov edx, 2501999793
mul edx
mov eax,edx
shr edx, 21

mov eax,edx
aam
add eax,3030h
bswap eax
shr eax,16
mov [szHours],ax

// Minutes
mov eax,3600000
mul edx
sub esi,eax
mov eax,esi

mov edx, 2345624806
mul edx
mov eax,edx
shr edx, 15

mov eax,edx
aam
add eax,3030h
bswap eax
shr eax,16
mov [szMin],ax

// Seconds
mov eax,60000
mul edx
sub esi,eax
mov eax,esi

mov edx, 2199023256
mul edx
mov eax,edx
shr edx, 9

mov eax,edx
aam
add eax,3030h
bswap eax
shr eax,16
mov [szSec],ax

// Fraction
mov eax,1000
mul edx
sub esi,eax
mov eax,esi
mov edx, 3435973837
mul edx
shr edx, 3

mov eax,edx
aam
add eax,3030h
bswap eax
shr eax,16
mov [szFrac],ax

ret


If someone wants to time it I would appreciate it, I am curious to see where it ends up on the time scale.

Donkey

EDIT: Sorry, left out one multiply and reformatted it a bit so it looks a little clearer.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

donkey

Mmmm, not too fast, based on 100 itterations it comes in at around 207 milliseconds, oh well it was a good idea while it lasted. I don't run MASM so I can't use MichaelW's test program, I wrote one to do basic timing though I did not bother with thread priority etc...

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

MichaelW

The procedures are so different that it's difficult to do valid comparisons. For timing without the string conversions Bin2Time and ConvertTime are at a disadvantage because you cannot reasonably remove the effects of the string conversion code (for ConvertTime I didn't even try to do so). For d2dtl and UpTime2 the method of passing the parameters are different, and for timing with the string conversions almost all of the time is spent in wsprintf. So for what it's worth, running on a P3 this is what I get without the string conversions:

200 cycles, Bin2Time
164 cycles, UpTime
24 cycles, d2dtl
30 cycles, UpTime2


And this is what I get with the string conversions, with significant variation in the cycle counts for all except ConvertTime, and using wsprintf to do the conversion for all except ConvertTime:

1401 cycles, Bin2Time
1786 cycles, UpTime
1249 cycles, d2dtl
1277 cycles, UpTime2
198 cycles, ConvertTime



[attachment deleted by admin]
eschew obfuscation

NightWare

to be fair, all data should be aligned  :wink

now the results are differents on my cpu,  :'( what a deception to see the results on another cpu...

donkey

Hi MichaelW,

If you comment out the conversion sections of converttime, you get the following for 100 itterations...

Line 128: eax = 8618
Line 147: eax = 8754
Line 166: eax = 8831
Line 185: eax = 8558
Line 204: eax = 8813
Line 223: eax = 8866
Line 242: eax = 8670
Line 261: eax = 8775


Or ~87.4 milliseconds, ofcourse the algorithm is pretty useless without conversion, as are all of the ones posted so I see these figures as meaningless. The only benchmark that means anything is the complete conversion from a binary value to a formatted string and for that I am pretty slow because of the choice of AAM and BSWAP, coming in as I said at around 207 milliseconds. Note that I tested with GetTickCount commented out as you did in your tests.

I should also note that my algorithm fails once the tick counter passes 99 days 23:59:59.99, this is because it can only convert 2 digit values.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

MichaelW

Quoteto be fair, all data should be aligned

Or at least all data except byte-size data that is accessed as bytes, and I failed to do that for yours and lingo's data, and Donkey's data that is accessed as words.
eschew obfuscation

ChrisLeslie

For an operation that has a slow resolution the whole concept of squeezing extra microseconds seems rather academic.
I would go for a simple GetTimeFormat and SYSTEMTIME struc and save a whole lot of my time. :U

Chris

Tight_Coder_Ex

Quote from: ChrisLeslie on February 16, 2008, 08:47:41 AM
For an operation that has a slow resolution the whole concept of squeezing extra microseconds seems rather academic.
I would go for a simple GetTimeFormat and SYSTEMTIME struc and save a whole lot of my time. :U

Chris
I guess it would be helpful if I was a little clearer as to the scope an purpose of the original post.

This is part of a algo to show typing speed in words per minute and total elapsed times as one enters text into a multi line control character by character.  Values in SYSTEMTIME would have to be converted and if someone is using the application at the end of the day (midnight) then additional calculation would be required. In this particular case speed is definitely not a concern as the average person has a maximum speed of 1 character every 145,000,000 nano seconds and the procedure processes every 450.  Formatting of output was another priority, as just for personal preferences I like to omit extraneous output whenever possible, ie: 0:00:03.415 to 3.415.

This thread did however open my mind to possibilities that I had not contemplated, especially using multiplication instead of division.  If I ever get involved with embedded systems that operate at considerably lower frequencies and less memory, these examples will serve as a good benchmark to optimize space and time.

donkey

Quote from: ChrisLeslie on February 16, 2008, 08:47:41 AM
For an operation that has a slow resolution the whole concept of squeezing extra microseconds seems rather academic.
I would go for a simple GetTimeFormat and SYSTEMTIME struc and save a whole lot of my time. :U

Chris

Sometimes it is interesting just to solve the problem, not worrying about whether you can find an application for the solution.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

NightWare

Quote from: Tight_Coder_Ex on February 16, 2008, 04:04:23 PM
This thread did however open my mind to possibilities that I had not contemplated, especially using multiplication instead of division.  If I ever get involved with embedded systems that operate at considerably lower frequencies and less memory, these examples will serve as a good benchmark to optimize space and time.
tight coder ex,
then we didn't loose our time  :wink

donkey,
few instructions removed, if it was a signature then forget this post :
    mov esi,eax

    ; Days
    mov edx, 3335999724
    mul edx
    shr edx, 26

    mov eax,edx
    aam
    add eax,3030h
    bswap eax
    shr eax,16
    mov WORD PTR [szDays],ax

    ; Hours
    mov eax,86400000
    mul edx
    sub esi,eax

    mov eax, 2501999793
    mul esi
    shr edx, 21

    mov eax,edx
    aam
    add eax,3030h
    bswap eax
    shr eax,16
    mov WORD PTR [szHours],ax

    ; Minutes
    mov eax,3600000
    mul edx
    sub esi,eax

    mov eax, 2345624806
    mul esi
    shr edx, 15

    mov eax,edx
    aam
    add eax,3030h
    bswap eax
    shr eax,16
    mov WORD PTR [szMin],ax

    ; Seconds
    mov eax,60000
    mul edx
    sub esi,eax

    mov eax, 2199023256
    mul esi
    shr edx, 9

    mov eax,edx
    aam
    add eax,3030h
    bswap eax
    shr eax,16
    mov WORD PTR [szSec],ax

    ; Fraction
    mov eax,1000
    mul edx
    sub esi,eax

    mov eax, 429496730
    mul esi

    mov eax,edx
    aam
    add eax,3030h
    bswap eax
    shr eax,16
    mov WORD PTR [szFrac],ax

    ret