+Random Terrain Posted March 22, 2016 Share Posted March 22, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 22, 2016 Share Posted March 22, 2016 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 Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted March 22, 2016 Share Posted March 22, 2016 With linear values like this, why not use a lookup table? 2 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 22, 2016 Share Posted March 22, 2016 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) Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 22, 2016 Share Posted March 22, 2016 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. 2 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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? Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted March 23, 2016 Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted March 23, 2016 Share Posted March 23, 2016 Not only way faster, but has the same cycle count for all inputs. I think that's beneficial too. 2 Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 23, 2016 Share Posted March 23, 2016 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 3 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 23, 2016 Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. 2 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 23, 2016 Share Posted March 23, 2016 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? Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 23, 2016 Author Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 23, 2016 Share Posted March 23, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.