Jump to content
Random Terrain

Which one is faster?

Recommended Posts

Which one is faster? This one:


   if _Hole_Width = 7 then var44 = %00000001 : goto __Skip_Hole_Width
   if _Hole_Width = 6 then var44 = %00000011 : goto __Skip_Hole_Width
   if _Hole_Width = 5 then var44 = %00000111 : goto __Skip_Hole_Width
   if _Hole_Width = 4 then var44 = %00001111 : goto __Skip_Hole_Width
   if _Hole_Width = 3 then var44 = %00011111 : goto __Skip_Hole_Width
   if _Hole_Width = 2 then var44 = %00111111 : goto __Skip_Hole_Width
   if _Hole_Width = 1 then var44 = %01111111

__Skip_Hole_Width



Or this one:

   var44 = 255
   for temp5 = 1 to _Hole_Width
   var44 = var44/2
   next



The for-next loop only saves 3 bytes, so if it's slower, I'll just use the if…thens.

 

 

Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

I think the first one; you do up to seven compares either way but the first one has direct assignment and no extra code per compare.

 

With many potential compares you could also load balance the structure to make it even faster:

 

if _Hole_Width <4 then goto load_balance_line

if _Hole_Width = 7 then var44 = %00000001 : goto __Skip_Hole_Width

if _Hole_Width = 6 then var44 = %00000011 : goto __Skip_Hole_Width

if _Hole_Width = 5 then var44 = %00000111 : goto __Skip_Hole_Width

if _Hole_Width = 4 then var44 = %00001111 : goto __Skip_Hole_Width

load_balance_line if _Hole_Width = 3 then var44 = %00011111 : goto __Skip_Hole_Width

if _Hole_Width = 2 then var44 = %00111111 : goto __Skip_Hole_Width

if _Hole_Width = 1 then var44 = %01111111

Share this post


Link to post
Share on other sites

Not sure how bB surfaces array objects or if you must embed asm for a lookup.

 

vwB supports BASIC array syntax:

 

data var44 %01111111, %0011111111, %00011111

rem var44(index)

Share this post


Link to post
Share on other sites

As WIZ says, a look-up-table is best. Something like...

 

 var44=Hole_Data[Hole_Width]
 data Hole_Data
 %11111111
 %01111111
 %00111111
 %00011111
 %00001111
 %00000111
 %00000011
 %00000001
end
I added a dummy value for the first entry where Hole_Width=0. Ideally stick the table out of the code flow, so you don't lose cycles skipping over it.
  • Like 2

Share this post


Link to post
Share on other sites

Thanks. I totally forgot about that option and it uses the same amount of space as the if…thens. Is there a way to tell how much faster it is than using a bunch of if…thens?

Share this post


Link to post
Share on other sites

Thanks. I totally forgot about that option and it uses the same amount of space as the if…thens. Is there a way to tell how much faster it is than using a bunch of if…thens?

 

It should actually roughly take 1/4th of space. Way faster.

  • Like 1

Share this post


Link to post
Share on other sites

I think you have something wrong. The table is way smaller than the if...then solution. The attached .bas outputs the size for all 3 routines during compile time.

 

The output is...

 

 routine 1:  88
 routine 2:  21
 routine 3:  18

...with the lookup table taking the least amount of space. You could shave 3 more bytes off from it if you use "noinlinedata".

 

Speed breakdown: the lookup table uses 10 or 11 cycles, constant. The if...then table uses 15 cycles best-case, 60 cycles worst-case. The loop uses 26 cycles best-case, 158 cycles worst-case.

routines_compared.bas

  • Like 3

Share this post


Link to post
Share on other sites

I think you have something wrong. The table is way smaller than the if...then solution. The attached .bas outputs the size for all 3 routines during compile time.

 

The output is...

 

 routine 1:  88
 routine 2:  21
 routine 3:  18
...with the lookup table taking the least amount of space. You could shave 3 more bytes off from it if you use "noinlinedata".

 

Speed breakdown: the lookup table uses 10 or 11 cycles, constant. The if...then table uses 15 cycles best-case, 60 cycles worst-case. The loop uses 26 cycles best-case, 158 cycles worst-case.

 

 

I don't doubt any of that and I see the same thing when I run your program, but this is what I'm seeing after compiling:

 

Compiling using the if…thens gives me 937 bytes of ROM space left.

 

Compiling using the for-next loop gives me 940 bytes of ROM space left.

 

Compiling using your data gives me 940 bytes of ROM space left.

 

Compiling using your data and using "set optimization noinlinedata" gives me 940 bytes of ROM space left.

 

 

I wonder why I'm seeing 940 for most versions?

Share this post


Link to post
Share on other sites

Wait, I might have figured it out. I was using "include fixed_point_math.asm" in this old code for some reason, but it looks like I don't need it. I'll put a rem in front of it and try the different versions again.

Share this post


Link to post
Share on other sites

Compiling with no version gives me 1000 bytes of ROM space left.

 

Compiling using the if…thens gives me 956 bytes of ROM space left.

 

Compiling using the for-next loop gives me 1000 bytes of ROM space left.

 

Compiling using your data gives me 1000 bytes of ROM space left.

 

Compiling using your data and using "set optimization noinlinedata" gives me 1000 bytes of ROM space left.

 

 

OK, so "fixed_point_math.asm" wasn't messing anything up. Getting rid of it just gave me some extra space. I still don't know why I'm not seeing a change for the ROM space left between most versions.

Share this post


Link to post
Share on other sites

Short story: sometimes bB manages to stick your code into wasted space, and the reported number doesn't change.

 

Long story: There's graphics data that needs to be aligned on memory page boundaries, so sometimes bB will waste space by sticking empty rom before the boundary, to ensure correct alignment.

 

If you're adding code prior to one of these, the code will take up that blank rom space and not report any extra usage. But eventually you'll add enough code to push the graphics data past it's required alignment and you'll lose a bunch of reported space at once.

  • Like 1

Share this post


Link to post
Share on other sites

Short story: sometimes bB manages to stick your code into wasted space, and the reported number doesn't change.

 

Long story: There's graphics data that needs to be aligned on memory page boundaries, so sometimes bB will waste space by sticking empty rom before the boundary, to ensure correct alignment.

 

If you're adding code prior to one of these, the code will take up that blank rom space and not report any extra usage. But eventually you'll add enough code to push the graphics data past it's required alignment and you'll lose a bunch of reported space at once.

 

Thanks. That's good to know. I'll stick each version in a small test program and then the difference should be obvious. I'll post the results for people who might be interested in the future.

  • Like 1

Share this post


Link to post
Share on other sites

Using a small test program:

Compiling with no version gives me 2879 bytes of ROM space left.

Compiling using the if…thens gives me 2791 bytes of ROM space left (88 bytes used).

Compiling using the for-next loop gives me 2858 bytes of ROM space left (21 bytes used).

Compiling using RevEng's data gives me 2861 bytes of ROM space left (18 bytes used).

Compiling using RevEng's data and using "set optimization noinlinedata" gives me 2864 bytes of ROM space left (15 bytes used).


That matches exactly what RevEng's test program shows, so you might want to use his program for comparing different chunks of code that do the same job.

  • Like 1

Share this post


Link to post
Share on other sites

Short story: sometimes bB manages to stick your code into wasted space, and the reported number doesn't change.

 

Long story: There's graphics data that needs to be aligned on memory page boundaries, so sometimes bB will waste space by sticking empty rom before the boundary, to ensure correct alignment.

 

If you're adding code prior to one of these, the code will take up that blank rom space and not report any extra usage. But eventually you'll add enough code to push the graphics data past it's required alignment and you'll lose a bunch of reported space at once.

I thought what you posted should be on the bB page, so I put it here:

 

randomterrain.com/atari-2600-memories-batari-basic-commands.html#memory

 

I guess that's the best place for it. I can move it if you know of a better place.

  • Like 2

Share this post


Link to post
Share on other sites

For both BASIC experts:

Agree the alternative method is faster, and faster still when using the alternative to batari BASIC because it's array based.

 

But to answer the original question, which routine is faster in bB and why?

 

Share this post


Link to post
Share on other sites

But to answer the original question, which routine is faster in bB and why?

I thought RevEng answered that:

 

Speed breakdown: the lookup table uses 10 or 11 cycles, constant. The if...then table uses 15 cycles best-case, 60 cycles worst-case. The loop uses 26 cycles best-case, 158 cycles worst-case.

  • Like 1

Share this post


Link to post
Share on other sites

I thought RevEng answered that:

 

Good answer, I missed that :) For times when you must use the if then block the load balancing optimization cuts the worst case in half; 20-30 cycles vs 15-60.

  • Like 1

Share this post


Link to post
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.

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...