Jump to content
IGNORED

Intybasic tips/tricks and Optimizing


Recommended Posts

Hi guys.

 

I started this thread for helping programmers to how to optimize Intybasic code.

 

Warning: Optimized code can look like a mess, but actually runs faster :)

 

E.G: (3 examples of code that do the same....)

 

rem test1

if a=0 then #sy=$0180:#sa=$194A+b
if a=1 then #sy=$0980:#sa=$194A+b
if a=2 then #sy=$0180:#sa=$195A+b
if a=3 then #sy=$0580:#sa=$196A+b
if a=4 then #sy=$0980:#sa=$197A+b
if a=5 then #sy=$0180:#sa=$197A+b
if a=6 then #sy=$0D80:#sa=$198A+b
if a=7 then #sy=$0580:#sa=$198A+b

a=a+1:if a=8 then a=0

 

rem test 2 - same as test1 just skip other ifs when "a" is found.

if a=0 then #sy=$0180:#sa=$194A+b:goto stopifa
if a=1 then #sy=$0980:#sa=$194A+b:goto stopifa
if a=2 then #sy=$0180:#sa=$195A+b:goto stopifa
if a=3 then #sy=$0580:#sa=$196A+b:goto stopifa
if a=4 then #sy=$0980:#sa=$197A+b:goto stopifa
if a=5 then #sy=$0180:#sa=$197A+b:goto stopifa
if a=6 then #sy=$0D80:#sa=$198A+b:goto stopifa
if a=7 then #sy=$0580:#sa=$198A+b

stopifa:

a=a+1:if a=8 then a=0

 

rem test3 - use of "on a goto"

on a goto a0,a1,a2,a3,a4,a5,a6,a7

a0: #sy=$0180:#sa=$194A+b:goto stopifa
a1: #sy=$0980:#sa=$194A+b:goto stopifa
a2: #sy=$0180:#sa=$195A+b:goto stopifa
a3: #sy=$0580:#sa=$196A+b:goto stopifa
a4: #sy=$0980:#sa=$197A+b:goto stopifa

a5: #sy=$0180:#sa=$197A+b:goto stopifa
a6: #sy=$0D80:#sa=$198A+b:goto stopifa
a7: #sy=$0580:#sa=$198A+b

stopifa:

a=a+1:if a=8 then a=0

 

 

i tested the code using the frame as counter :) 1000 times loop

 

mode 1

cls

print at 1,<5>frame

for #c=1 to 1000

 

rem insert code here

 

next

print at 21,<5>frame

 

stop:goto stop

 

test1 finished at frame 00299.

test2 finished at frame 00227.

test3 finished at frame 00169.

 

I have also tested the "ON A GOTO" agains "IFs", it seems like, more ifs more avantage does "ON A GOTO" have against if. Ofcause assume its not picking the first choice all the time :)

 

I think on two ifs the speed is almost the same.

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Like 2
Link to comment
Share on other sites

For this particular pattern, a lookup table would be the best of all, although ON-GOTO seems really close.

 

I benchmarked all 4 options in one BAS file. As you can see from the screen shot, the ON-GOTO was just slightly slower than the table lookup. I measured this with IntyBASIC 1.2.8.

 

table.bas

mode 1
cls
a = 0
wait
#x = frame
for #c=1 to 1000
    if a=0 then  #sy=$0180:#sa=$194A+b
    if a=1 then  #sy=$0980:#sa=$194A+b
    if a=2 then  #sy=$0180:#sa=$195A+b
    if a=3 then  #sy=$0580:#sa=$196A+b
    if a=4 then  #sy=$0980:#sa=$197A+b
    if a=5 then  #sy=$0180:#sa=$197A+b
    if a=6 then  #sy=$0D80:#sa=$198A+b
    if a=7 then  #sy=$0580:#sa=$198A+b
    a=a+1:if a=8 then a=0
next
#x = frame - #x
print at 1,<5>#x

a = 0
wait
#x = frame
for #c=1 to 1000
    if a=0 then #sy=$0180:#sa=$194A+b:goto stopifa
    if a=1 then #sy=$0980:#sa=$194A+b:goto stopifa
    if a=2 then #sy=$0180:#sa=$195A+b:goto stopifa
    if a=3 then #sy=$0580:#sa=$196A+b:goto stopifa
    if a=4 then #sy=$0980:#sa=$197A+b:goto stopifa
    if a=5 then #sy=$0180:#sa=$197A+b:goto stopifa
    if a=6 then #sy=$0D80:#sa=$198A+b:goto stopifa
    if a=7 then #sy=$0580:#sa=$198A+b
    stopifa:
    a=a+1:if a=8 then a=0
next
#x = frame - #x
print at 21,<5>#x


a = 0
wait
#x = frame
for #c=1 to 1000
    on a goto a0,a1,a2,a3,a4,a5,a6,a7
    a0: #sy=$0180:#sa=$194A+b:goto stopifa2
    a1: #sy=$0980:#sa=$194A+b:goto stopifa2
    a2: #sy=$0180:#sa=$195A+b:goto stopifa2
    a3: #sy=$0580:#sa=$196A+b:goto stopifa2
    a4: #sy=$0980:#sa=$197A+b:goto stopifa2
    a5: #sy=$0180:#sa=$197A+b:goto stopifa2
    a6: #sy=$0D80:#sa=$198A+b:goto stopifa2
    a7: #sy=$0580:#sa=$198A+b
    stopifa2:
    a=a+1:if a=8 then a=0
next
#x = frame - #x
print at 41,<5>#x

a = 0
wait
#x = frame
for #c=1 to 1000
    #sy=ytbl(a) : #sa=atbl(a)+b
    a=a+1:if a=8 then a=0
next
#x = frame - #x
print at 61,<5>#x


stop:goto stop

ytbl: DATA $0180, $0980, $0180, $0580, $0980, $0180, $0D80, $0580
atbl: DATA $194A, $194A, $195A, $196A, $197A, $197A, $198A, $198A

post-14113-0-65994900-1490425345_thumb.gif

  • Like 2
Link to comment
Share on other sites

BTW, some benchmarking tips, when using FRAME as your measurement:

  • Put a WAIT just before you grab FRAME the first time, so you're synced to the display interrupt
  • Don't print the starting/ending frame number: It costs cycles to print! Instead, just copy the frame number to a variable and subtract at the end. Then print. The cost of the print won't be in the total.
  • Lookup tables are your friends!
Link to comment
Share on other sites

The "On GoTo" is useful as a pattern because it covers conditional value retrieval as well as conditional code execution. If your values fit neatly in a look-up table, that is obviously the best choice. However, if they are computed or if you need to do work based on a particular condition, the "On GoTo" would be the best alternative.

 

If your program has the need of both of these features (to wit, conditional value retrieval and code execution), and you are easily confused like some of us are, then sticking to a pattern that does both may help make your code easier to read and more predictable, at a slight cost in performance.

 

As with many things, your mileage may vary. :)

 

-dZ.

  • Like 2
Link to comment
Share on other sites

Also, if you change this:

a = a + 1 : if a = 8 then a = 0

to this:

a = (a + 1) AND 7

everything gets faster:

attachicon.giftable2_bas.gif

That is unreal. I don't really understand how AND works but I understand the result.

 

I realize the difference is small overall but I'm very impressed. now I will need to look at all the loops in my code and see if I can save some cycles with lookup tables,On Goto and using the AND in my counting..

Link to comment
Share on other sites

I've optimized more IntyBASIC and the remainder operator converts to AND operator for most power of 2 constants.

 

 

 a = a % 8    same as    a = a AND 7
 a = a % 16  same as    a = a AND 15

 

This is the same because given the inherent slowness of CP1610 processor, I've keeped the unsigned nature of division and remainder, because the test for signedness would be very slow.

 

Anyway if you ever need signed division, this would be the right way.

 

 

    IF a < 0 THEN a = -(-a / b) ELSE a = a / b
  • Like 1
Link to comment
Share on other sites

That is unreal. I don't really understand how AND works but I understand the result.

 

I realize the difference is small overall but I'm very impressed. now I will need to look at all the loops in my code and see if I can save some cycles with lookup tables,On Goto and using the AND in my counting..

 

Bitwise AND is simple to understand, it even follows some intuitive common sense. When you apply AND on two expressions, the result is only true when both are true. In bits, this means that the result is "1" only when both inputs are "1". For instance:

A AND B = C
-----------
0     0   0
0     1   0
1     0   0
1     1   1

You can extend this by applying the same function on non-binary numbers. In such cases, each individual bit on one number is ANDed with its corresponding bit on the other. Like this:

5 = 00000101
3 = 00000011

5 AND 3 = 00000101 AND 00000011

  00000101
  00000011
  --------
  00000001

This is typically called "applying a mask" because it works in the same way as having a picture "masked out" with a cover that lets only certain parts shine through. In other words, you take any number and apply to it a "mask," and what comes out are only those bits that are "1" which are also represented in the mask.

 

Now take the example of a mask like "7" (00000111). This is a very common mask because it means "mask out the number and only allow through those bits which fall on values less than 8." In other words, the number would be cycled from 0 through 7 and as soon as it gets higher than that, it will go back and cycle again by virtue of discarding the higher bits. Here's a demonstration:

 0 : 00000000 AND 00000111 = -----000 = 0
 1 : 00000001 AND 00000111 = -----001 = 1
 2 : 00000010 AND 00000111 = -----010 = 2
 3 : 00000011 AND 00000111 = -----011 = 3
 4 : 00000100 AND 00000111 = -----100 = 4
 5 : 00000101 AND 00000111 = -----101 = 5
 6 : 00000110 AND 00000111 = -----110 = 6
 7 : 00000111 AND 00000111 = -----111 = 7
 8 : 00001000 AND 00000111 = -----000 = 0
 9 : 00001001 AND 00000111 = -----001 = 1
10 : 00001010 AND 00000111 = -----010 = 2
11 : 00001011 AND 00000111 = -----011 = 3
12 : 00001100 AND 00000111 = -----100 = 4
13 : 00001101 AND 00000111 = -----101 = 5
14 : 00001110 AND 00000111 = -----110 = 6
15 : 00001111 AND 00000111 = -----111 = 7
...

Notice that this sort of "number cycling" is only possible because the mask is one less than a power of two (1 - 2^n). In other words, the mask fills up all the bits up to but not including the next power of two.

 

Not only is this useful to cycle numbers within a power-of-two range, it also gives you the modulo of a number, that is, the reminder after division of a power-of-two. Remember, a division by a power-of-two is the same as shifting right, which causes it to discard the lower-bits. For instance:

5 ÷ 2 = 00000101 >> 1 = 00000010     ...        (1)
                       [ result ]   [one bit shifted and discarded]

This is the same as saying:

5 ÷ 2 = 2 ... reminder = 1

What the AND operator does in this case is that it masks only those bits which would have been shifted out and discarded, and leaves them in to the exclusion of the rest. The result is the reminder.

5 AND (2^1 - 1) = 00000101 AND 00000001 = -------1

I hope this helps. :)

 

Other non-powers-of-two masks are very useful to test specific bits on registers, or to negate numbers, etc.

 

-dZ.

Edited by DZ-Jay
  • Like 3
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...