The LeapYear
#1
Here, Dale Yarker shows a fast Way to find a Leap Year.

This looks very nice - for 32-Bit Systems.

Programming in 16-Bit PB 3.5  for DOS, I can only make  Cry eyes…  Huh

I use a much slower routine, calculating results for julian and gregorian calendar.

Code:
Declare _
Function iFeb(ByVal iJahr As Integer)        As Integer
Function iFeb(ByVal iJahr As Integer) Public As Integer
  If iJahr < 1582% then
    Function = 29% _
             + ( _
                 ( _
                   iJahr Mod 4% _
                 ) _
                 <> 0% _
               )
  Else
    Function = 29% _
             + ( _
                 ( _
                   iJahr/4 _
                 ) _
                 <> _
                 ( _
                   iJahr\4 _
                 ) _
                 Or _
                 ( _
                   iJahr/100 _
                 ) _
                 = _
                 ( _
                   iJahr\100 _
                 ) _
                 And _
                 ( _
                   iJahr/400 _
                 ) _
                 <> _
                 ( _
                   iJahr\400 _
                 ) _
               )
  End If
End Function

Does someone has an idea, how this could look in 16-Bit-Inline-Asm?
Reply
#2
Biggest difference between 32 and 16 bit should be AX instead of EAX, BX instead of EBX, etcetera.
Also, % instead of ???.
Been a very long time. Does PBDOS allow ! or must it be ASM?

I could make a try.
Reply
#3
(03-07-2025, 11:49 PM)Dale Yarker Wrote: Biggest difference between 32 and 16 bit should be AX instead of EAX, BX instead of EBX, etcetera.
Also, % instead of ???.
Been a very long time. Does PBDOS allow ! or must it be ASM?

I could make a try.

PB 3.5 allows both, Asm and !.

A try would be great.
Reply
#4
In source code at:  Leap days (or not) in February for PBDOS

(forgot the Julian part. needed?)
Reply
#5
(03-08-2025, 08:50 AM)Dale Yarker Wrote: In source code at:  Leap days (or not) in February for PBDOS

(forgot the Julian part. needed?)

Yes, Julian is needed.

Thank you very much, Dale!
Reply
#6
Just updated source code. Worked on it without waiting reply.

Suggest you test more thoroughly than I did in PBMAIN.


Code:
'changed post 1 code to operation per line
'if you like your style it is "legel"
'maybe just me, I figure out what you're were doing
'for example, I couldn't see that you were starting at 29
'because logic ops return -1 (or 0), so + was actually - 1
'when not 0, repeat, REPEAT, if you like it as is okay, but
'it will come back different if I need to read it
#compile exe
#dim all
declare _
function iFeb(byval iJahr as integer)        as integer
function iFeb(byval iJahr as integer) Public as integer
  if iJahr < 1582% then
    function = 29% + ((iJahr mod 4%) <> 0%)
  else
    function = 29% + ((iJahr/4) <> (iJahr\4) or _
                    (iJahr/100) = (iJahr\100) and _
                    (iJahr/400) <> (iJahr\400))
  end if
end function
'Cheers,

(tried make a separate post (twice), this forum combined it with previous)
Reply
#7
Thank you a lot, Dale.

In the past, I used to write very ugly codesnakes and when I looked at them years later, Ihat no idea, what I had done several years ago.

So, now, I use this kind of style.
It gives me the chance to comment every little step on the right part of the screen.

Sometimes I feel like writing a book. But this makes me understand today, what I createt in the last decade.

Your alternative looks good, too. Thenk you for this logical insparation.
Reply
#8
I optimized your Inline-Asm code for PB 3.5 and it worked very fine now! :-)
Reply
#9
For testing the speed of the routines, I wrote a little benchmark programm, calculating the given years in your code each 65535 times with my Basic- ans your Inline-Asm-code.

The Julian routine in PB is relatively fast, in contrast to the Gregorean, where Asm shows its power to BASIC!






Quote:03-09-2025    00:25:24      Linux - DOSBox-X German numbers!

Testing the speed of leapyear calculaition in (Power)BASIC and Inline-Asm

Test 1, part 1: Calculating 65535 times in BASIC-Code:
2000 leap? yes - Test took 4.436.195,000 Millisekunden

Test 1, part 2: Calculating 65535 times in Inline-Asm-Code:
2000 leap? yes - Test took 1.059.302,000 Millisekunden
Inline-Asm is      4,187847 times faster here


Test 2, part 1: Calculating 65535 times in BASIC-Code:
2100 leap? no  - Test took 4.413.717,000 Millisekunden

Test 2, part 2: Calculating 65535 times in Inline-Asm-Code:
2100 leap? no  - Test took  971.019,000 Millisekunden
Inline-Asm is      4,545449 times faster here


Test 3, part 1: Calculating 65535 times in BASIC-Code:
2104 leap? yes - Test took 4.435.798,000 Millisekunden

Test 3, part 2: Calculating 65535 times in Inline-Asm-Code:
2104 leap? yes - Test took  971.021,000 Millisekunden
Inline-Asm is      4,568179 times faster here


Test 4, part 1: Calculating 65535 times in BASIC-Code:
2103 leap? no  - Test took 4.413.715,000 Millisekunden

Test 4, part 2: Calculating 65535 times in Inline-Asm-Code:
2103 leap? no  - Test took  728.261,000 Millisekunden
Inline-Asm is      6,060622 times faster here


Test 5, part 1: Calculating 65535 times in BASIC-Code:
1204 leap? yes - Test took  838.600,000 Millisekunden

Test 5, part 2: Calculating 65535 times in Inline-Asm-Code:
1204 leap? yes - Test took  728.261,000 Millisekunden
Inline-Asm is      1,151510 times faster here


Test 6, part 1: Calculating 65535 times in BASIC-Code:
1201 leap? no  - Test took  816.533,000 Millisekunden

Test 6, part 2: Calculating 65535 times in Inline-Asm-Code:
1201 leap? no  - Test took  706.190,000 Millisekunden
Inline-Asm is      1,156251 times faster here



03-08-2025    24:26:54      Linux - DOSBox German numbers!

Testing the speed of leapyear calculaition in (Power)BASIC and Inline-Asm

Test 1, part 1: Calculating 65535 times in BASIC-Code:
2000 leap? yes - Test took 4.394.786,000 Millisekunden

Test 1, part 2: Calculating 65535 times in Inline-Asm-Code:
2000 leap? yes - Test took 1.048.882,000 Millisekunden
Inline-Asm is      4,189972 times faster here


Test 2, part 1: Calculating 65535 times in BASIC-Code:
2100 leap? no  - Test took 4.370.329,000 Millisekunden

Test 2, part 2: Calculating 65535 times in Inline-Asm-Code:
2100 leap? no  - Test took  961.471,000 Millisekunden
Inline-Asm is      4,545461 times faster here


Test 3, part 1: Calculating 65535 times in BASIC-Code:
2104 leap? yes - Test took 4.392.178,000 Millisekunden

Test 3, part 2: Calculating 65535 times in Inline-Asm-Code:
2104 leap? yes - Test took  961.471,000 Millisekunden
Inline-Asm is      4,568186 times faster here


Test 4, part 1: Calculating 65535 times in BASIC-Code:
2103 leap? no  - Test took 4.370.327,000 Millisekunden

Test 4, part 2: Calculating 65535 times in Inline-Asm-Code:
2103 leap? no  - Test took  721.107,000 Millisekunden
Inline-Asm is      6,060580 times faster here


Test 5, part 1: Calculating 65535 times in BASIC-Code:
1204 leap? yes - Test took  830.365,000 Millisekunden

Test 5, part 2: Calculating 65535 times in Inline-Asm-Code:
1204 leap? yes - Test took  721.107,000 Millisekunden
Inline-Asm is      1,151514 times faster here


Test 6, part 1: Calculating 65535 times in BASIC-Code:
1201 leap? no  - Test took  808.510,000 Millisekunden

Test 6, part 2: Calculating 65535 times in Inline-Asm-Code:
1201 leap? no  - Test took  699.252,000 Millisekunden
Inline-Asm is      1,156250 times faster here



03-09-2025    00:27:32      Linux - DOSEmu German numbers!

Testing the speed of leapyear calculaition in (Power)BASIC and Inline-Asm

Test 1, part 1: Calculating 65535 times in BASIC-Code:
2000 leap? yes - Test took  131.325,000 Millisekunden

Test 1, part 2: Calculating 65535 times in Inline-Asm-Code:
2000 leap? yes - Test took    13.212,000 Millisekunden
Inline-Asm is      9,939827 times faster here


Test 2, part 1: Calculating 65535 times in BASIC-Code:
2100 leap? no  - Test took  126.944,000 Millisekunden

Test 2, part 2: Calculating 65535 times in Inline-Asm-Code:
2100 leap? no  - Test took    12.813,000 Millisekunden
Inline-Asm is      9,907438 times faster here


Test 3, part 1: Calculating 65535 times in BASIC-Code:
2104 leap? yes - Test took  127.343,000 Millisekunden

Test 3, part 2: Calculating 65535 times in Inline-Asm-Code:
2104 leap? yes - Test took    12.585,000 Millisekunden
Inline-Asm is    10,118633 times faster here


Test 4, part 1: Calculating 65535 times in BASIC-Code:
2103 leap? no  - Test took  127.684,000 Millisekunden

Test 4, part 2: Calculating 65535 times in Inline-Asm-Code:
2103 leap? no  - Test took    10.438,000 Millisekunden
Inline-Asm is    12,232612 times faster here


Test 5, part 1: Calculating 65535 times in BASIC-Code:
1204 leap? yes - Test took    13.623,000 Millisekunden

Test 5, part 2: Calculating 65535 times in Inline-Asm-Code:
1204 leap? yes - Test took    11.585,000 Millisekunden
Inline-Asm is      1,175917 times faster here


Test 6, part 1: Calculating 65535 times in BASIC-Code:
1201 leap? no  - Test took    14.706,000 Millisekunden

Test 6, part 2: Calculating 65535 times in Inline-Asm-Code:
1201 leap? no  - Test took    10.805,000 Millisekunden
Inline-Asm is      1,361037 times faster here
Reply
#10
Arithmetic ops by powers of 2 can be done a bit faster by not using *, \ or MOD (likely you know of 2 them). For example:
X * 4 can be SHIFT LEFT X, 2
X \ 4 can be SHIFT RIGHT X, 2
X MOD 4 can be X AND 3

Those can be done in BASIC code so difference between BASIC and ASM timing may be made smaller.

MOD is a divide with the remainder returned instead of the quotient.
Your BASIC code can be quicker with MOD 100 and MOD 400 than 2 divides by 100 and 2 divides by 400.

In ASM the DIV instruction returns both quotient and remainder. 100 is not a power 0f 2, so had to divide by 100. The remainder used as MOD 100 and quotient used with X AND as MOD 400.

The 1,15 times faster for 1204 and 1201 shows how small the difference is between MOD and AND.

------------------------------------------------------

I think my ASM can be speeded up a tiny bit by removing 3 PUSHes and 3 POPs. (iJahr should stay in the stack, not be made a register variable.)
If PBDOS had $REGISTER NONE I'd have used it just to make sure. Also, "make it work first", then try reversible changes.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)