Jump to content
IGNORED

XB speed test. Trying to work out fastest XB Compiler speed. Interesting result!


Bones-69

Recommended Posts

I've been developing an idea in Magellan that looks great and everything about my idea seems doable, but I will have a lot going on at once so I wrote a little program to act as a "speed check". Initially I expected to visually see a difference in the speed of the little ball moving across the screen but this was not to be.

 

My method was to run each test for exactly two minutes in native XB. I used a stopwatch and stopped the program each time at 120 seconds and then recorded the value of COUNT (which had been incremented every cycle). A higher number means a faster result. 

 

Test #1. Count 3433

200 A=B(A):: COUNT=COUNT+1
210 CALL LOCATE(#1,100,A):: GOTO 200

 

Test #2. Count 3066 *Slowest

240 A=A+1 :: COUNT=COUNT+1 :: IF A=193 THEN A=1
250 CALL LOCATE(#1,100,A):: GOTO 240

 

Test #3. Count 3888 *Fastest

280 FOR A=1 TO 192 :: COUNT=COUNT+1
290 CALL LOCATE(#1,100,A):: NEXT A :: GOTO 280

 

Test #4. Count 3500

330 A=A+0.05 :: COUNT=COUNT+1
340 CALL LOCATE(#1,100,A):: GOTO 330

 

Test #4 came a bit later in the thought process. Test #4 is the same as Test #2 less the IF statement.

 

I expected the FOR/NEXT method to be the quickest, which it was. However if Test #1 and Test #4 are fair to compare, then this result surprises me a lot. If my method here is sound, then A=A+1 executes quicker than A=B(A). I simply expected anything that involved maths to be a lot slower than simply fetching a known variable. Even now this doesn't feel right.

 

Also wondering if these results would transfer to XB compiled code? Which is ultimately what I am trying to work out here....  Unfortunately this is not easily testable with compiled code using my simple methods.

 

Another noteworthy is how expensive the IF statement actually was. In Test #2 it seems to have consumed approx 15% of the processing time just to compare A against a value of 193.

 

Maybe none of this is a surprise.... But not knowing how things work under the bonnet I gotta tool around like this and hope to fluke a good result. 

 

 

[code]

100 DIM B(193):: FOR I=0 TO 192 :: B(I)=I+1 :: NEXT I :: B(193)=1
110 CALL CLEAR :: CALL CHAR(128,"3C7EFFFF7E3C"):: CALL SPRITE(#1,128,2,100,1)
120 PRINT "1. A=B(A) ERR CHECKING N/A"
130 PRINT "2. A=A+1 WITH ERR CHECKING"
140 PRINT "3. FOR/NEXT ERR CHECKING N/A"
150 PRINT "4. A=A+0.05 N0 ERR CHECKING"
160 ACCEPT AT(24,1)SIZE(1)VALIDATE("1234"):A$ :: IF LEN(A$)=0 THEN 160 ELSE CHOICE=VAL(A$)
170 CALL CLEAR :: PRINT "VIEW VARIABLE *COUNT* AT END": : : :: ON CHOICE GOTO 180,220,260,300
180 ! EXAMPLE 1
190 PRINT "1.":"A=B(A) ERR CHECKING N/A"
200 A=B(A):: COUNT=COUNT+1
210 CALL LOCATE(#1,100,A):: GOTO 200
220 ! EXAMPLE 2
230 PRINT "2.":"A=A+1 WITH ERR CHECKING"
240 A=A+1 :: COUNT=COUNT+1 :: IF A=193 THEN A=1
250 CALL LOCATE(#1,100,A):: GOTO 240
260 ! EXAMPLE 3
270 PRINT "3.":"FOR/NEXT ERR CHECKING N/A"
280 FOR A=1 TO 192 :: COUNT=COUNT+1
290 CALL LOCATE(#1,100,A):: NEXT A :: GOTO 280
300 ! EXAMPLE 4
310 PRINT "4.":"A=A+0.05 WITHOUT ERR        CHECKING"
320 PRINT :"IGNORE MOVEMENT SPEED" :: A=1
330 A=A+0.05 :: COUNT=COUNT+1
340 CALL LOCATE(#1,100,A):: GOTO 330

[/code]

Link to comment
Share on other sites

If you look at the Source Code of XB (GPL/Assembly ROM) you will find A=A+0.05 as this line has more tokens, then A=B(A)

More tokens take longer to interpret than less tokens.

A IF comparison THEN value has way more tokens for the interpreter to solve and many more Floating Point numbers too.

XB is built on all numbers as Floating Point so the less often you use any Floating Point numbers the better.

 

I am working on a integer token for XB that would eliminate this problem of speed for XB.

This requires a rewrite of XB ROMs so you are welcome to help if you want...

 

XBROMS.zip

  • Like 2
Link to comment
Share on other sites

2 hours ago, Bones-69 said:

I've been developing an idea in Magellan that looks great and everything about my idea seems doable, but I will have a lot going on at once so I wrote a little program to act as a "speed check". Initially I expected to visually see a difference in the speed of the little ball moving across the screen but this was not to be.

 

My method was to run each test for exactly two minutes in native XB. I used a stopwatch and stopped the program each time at 120 seconds and then recorded the value of COUNT (which had been incremented every cycle). A higher number means a faster result. 

 

Test #1. Count 3433

200 A=B(A):: COUNT=COUNT+1
210 CALL LOCATE(#1,100,A):: GOTO 200

 

Test #2. Count 3066 *Slowest

240 A=A+1 :: COUNT=COUNT+1 :: IF A=193 THEN A=1
250 CALL LOCATE(#1,100,A):: GOTO 240

 

Test #3. Count 3888 *Fastest

280 FOR A=1 TO 192 :: COUNT=COUNT+1
290 CALL LOCATE(#1,100,A):: NEXT A :: GOTO 280

 

Test #4. Count 3500

330 A=A+0.05 :: COUNT=COUNT+1
340 CALL LOCATE(#1,100,A):: GOTO 330

 

Test #4 came a bit later in the thought process. Test #4 is the same as Test #2 less the IF statement.

 

I expected the FOR/NEXT method to be the quickest, which it was. However if Test #1 and Test #4 are fair to compare, then this result surprises me a lot. If my method here is sound, then A=A+1 executes quicker than A=B(A). I simply expected anything that involved maths to be a lot slower than simply fetching a known variable. Even now this doesn't feel right.

 

Also wondering if these results would transfer to XB compiled code? Which is ultimately what I am trying to work out here....  Unfortunately this is not easily testable with compiled code using my simple methods.

 

Another noteworthy is how expensive the IF statement actually was. In Test #2 it seems to have consumed approx 15% of the processing time just to compare A against a value of 193.

 

Maybe none of this is a surprise.... But not knowing how things work under the bonnet I gotta tool around like this and hope to fluke a good result. 

This is neat to see. 

I don't use the BASIC compiler but I think you can see the resulting Assembler code, no?

That would be where you could see  the difference in the number of instructions between Test #2 and Test #4. 

 

I have been hobbying away at compiler code generation myself and yes, when you put "anything" inside a tight loop it shows up big time.

The minimal machine code loop is one instruction, so if you put anything inside, it adds more to the time very quickly. 

 

 

  • Like 1
Link to comment
Share on other sites

49 minutes ago, Asmusr said:

Maybe an array look-up involves a multiplication while the other is just an addition?

Integer arrays would typically need the (index*2)  so that can be a shift 1 bit left.

Then add that number to the array base, then retrieve or store the value. 

If the compiler can figure it out, the indexed addressing mode is the fastest in my experiments since it's one instruction. 

 

A poor compiler doing A=A+1 might Generate

LI   R1,AVAR 
MOV *R1,R2
INC  R2 
MOV  R2*R1

 

A good compiler would generate code like a human would do. 

INC @AVAR  

 

I am a novice at this "generate native code" compiler stuff but I find it fascinating. 

  • Like 1
Link to comment
Share on other sites

Here are some thoughts about most of the posts here.

1 - If I understand the purpose of the test correctly, Bones69 is trying to determine which instructions execute fastest.

The examples have a lot of extra instructions in them such as CALL LOCATE(#1,100,A) which is in all of them.

This sort of test is easy in XB:

10 FOR I=1 TO 500::A=A+1::NEXT I

By trial and error you can set the number of loops to a reasonable number that yields a run time of 1 or 2 minutes. You should also do an empty loop and time that. By subtracting that time from the first, you now know how long it takes to do A=A+1 500 times.

You can put any instruction you want inside the loop. Of course you can compile this for testing its speed in a compiled program, but because of the extra speed you would probably have to nest loops. Since compiled code is so much faster, it would be hard to know how many times to loop, and it is a pain to recompile for just one simple change. But something like this should suffice by letting you choose a value that runs in a couple of minutes.

10 INPUT JJ::FOR J=1 TO jj::FOR I=1 TO 30000::A=A+1::NEXT I::NEXT J

Since you can run compiled programs from XB, you should be able to use the Classic99 clock to do the timing for you.

2 - In compiled code, the interpreter has to first find the location of the numeric variable. It first checks to see if it is an array or a simple variable. If it is a simple variable it knows where to find the value. If it is an array, (Let's say the variable was X(2,3)  it has to determine if it is option base 0 or option base 1. Then the dimensions of the array. If it was DIM X(3,4) it has to fetch 2 numbers and use those to determine where the actual value of X(2,3) is stored. Arrays are very useful, but if speed is important, then they are not your friend.

3 - Compiled code is not assembly code. I am told it is called "threaded code"

The XB line 10 X=X+1 becomes:

L10
       DATA ADD,NV1,NC1,NT1
       DATA LET,NV1,NT1

there is not an assembly instruction in there and there is no easy way to count the assembly instructions.

The interpreter takes the NV1 (which is X) and adds NC1 (which is 1) and stores the results in a temporary value (NT1), Then NT1 is moved to NV1.

This is cumbersome and certainly more complex than INC @NV1 would be. But it is universal and is the same whether the constant is 1 or 4567

 

 

 

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Cool info here. Lot of stuff I never knew.

 

Senior_Falcon I did a little more testing and was astonished to see the true cost of using 3 dimensional arrays. The testing method you have suggested seems solid.

 

I might throw a little time at this. It would be interesting to get some insight into a whole range of functions and methods both for XB and for the relative Compiled code. I'm keen to throw everything into a loop and see if there are any unusual surprises. I haven't used the Classic timer so will read up on that as well. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...