1980gamer Posted September 12, 2021 Share Posted September 12, 2021 I am trying to squeeze some performance out of a comparison. I cannot see much difference between And/Or in XB Does it make a difference Compiled? So, if the first element where true the OR would be faster. If it where false the AND would be faster. But what is happening in the actual game, the lower elements matter the most. So, the cls(7) will be true or false most often followed by 8,9 etc. Next can I replace GCHAR with a PEEK? Would it matter? Compiled? I am getting close to finishing a game, but I want to tighten it up... I plan on refactoring a little and untangling some of the spaghetti but the key part where the speed is most important is the compare and gchar. 10 DIM CLS(20) 15 FOR X=7 TO 15 20 CLS(X)=32 25 NEXT X 30 FOR X=1 TO 1000 40 IF CLS(7)=32 AND CLS(8)=32 AND CLS(9)=32 AND CLS(10)=32 AND CLS(11)=32 AND CLS(12)=32 AND CLS(13)=32 AND CLS(14)=32 AND CLS(15)=32 THEN 50 ELSE END 50 NEXT X VS 10 DIM CLS(20) 15 FOR X=7 TO 15 20 CLS(X)=32 25 NEXT X 30 FOR X=1 TO 1000 40 IF CLS(7)>92 OR CLS(8)>92 OR CLS(9)>92 OR CLS(10)>92 OR CLS(11)>92 OR CLS(12)>92 OR CLS(13)>92 OR CLS(14)>92 OR CLS(15)>92 THEN END ELSE 50 50 NEXT X Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 13, 2021 Share Posted September 13, 2021 In compiled code, OR is slightly faster than AND. But I don't think you would be able to notice. Using arrays is definitely slower, both compiled and in XB. Wherever possible you should use variables. Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 13, 2021 Author Share Posted September 13, 2021 2 minutes ago, senior_falcon said: In compiled code, OR is slightly faster than AND. But I don't think you would be able to notice. Using arrays is definitely slower, both compiled and in XB. Wherever possible you should use variables. Thanks for the reply. I have changed to the OR version. I was using this array because I had already been using it in another part of the program. So, rather then create more variables. Also, makes looping easy.. Hmm, I will try to use normal vars rather than array and see if that helps. I think this will take a lot more statements to complete the same task. But I have another subroutine that I may be able to piggyback on and kill to birds with one stone. Oh fun! LOL. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 13, 2021 Share Posted September 13, 2021 6 hours ago, 1980gamer said: 40 IF CLS(7)>92 OR CLS(8)>92 OR CLS(9)>92 OR CLS(10)>92 OR CLS(11)>92 OR CLS(12)>92 OR CLS(13)>92 OR CLS(14)>92 OR CLS(15)>92 THEN END ELSE 50 When I look at all those logical conditions I find myself wondering if there is one of them that is critical? Maybe there are two that are show-stoppers. If so those could be part of an IF statement so that you shortcut testing everything IF you don't need to. Using logical flags with AND and OR can save time for two conditions vs IF under the right conditions, but I think you are forcing the machine to compute all of the logical operations, even if you fail the first one. That could be a bottle-neck maybe. (?) But maybe it has to be that way for your program. Just a thought. The compiler make fast code but it's not very speedy processor under the hood. 1 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 13, 2021 Author Share Posted September 13, 2021 2 hours ago, TheBF said: When I look at all those logical conditions I find myself wondering if there is one of them that is critical? Maybe there are two that are show-stoppers. If so those could be part of an IF statement so that you shortcut testing everything IF you don't need to. Using logical flags with AND and OR can save time for two conditions vs IF under the right conditions, but I think you are forcing the machine to compute all of the logical operations, even if you fail the first one. That could be a bottle-neck maybe. (?) But maybe it has to be that way for your program. Just a thought. The compiler make fast code but it's not very speedy processor under the hood. Unfortunately any one of these conditions could be true. The lower ones are most probable at least. I think I can use a constant for the next segment of the program and that "may" help? The or vs. and was noticeable within the actual game. Complied even more so. I am doing a block of gchar's into the cls(x) values. I was calling the GCHARS on each pass. Dropping the values into the array was a huge increase in speed. But I still want to squeeze a little more out of it! Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted September 13, 2021 Share Posted September 13, 2021 36 minutes ago, 1980gamer said: I am doing a block of gchar's into the cls(x) values. I was calling the GCHARS on each pass. Dropping the values into the array was a huge increase in speed. But I still want to squeeze a little more out of it! Depending upon the comparisons necessary, what about taking the value returned by GCHAR and placing it into a string using CHR$(), then making an en-mass comparison? For instance 10 S$="" :: FOR I=4 TO 13 :: CALL GCHAR(R,I,X) :: S$=S$&CHR$(X) :: NEXT I ! WHERE R IS THE SCREEN ROW 20 IF S$=" " THEN 100 ! TEN SPACES 30 REM THIS IS THE REST OF THE PROGRAM 100 REM THIS IS WHERE WE WANT TO GO If you know CTRL key character codes, you could still use this for un-printable characters. Though it makes copy and paste text listings impossible. Honestly not sure if this will make it faster, but it could make it easier to program. Quote Link to comment Share on other sites More sharing options...
RXB Posted September 13, 2021 Share Posted September 13, 2021 (edited) 10 CALL HGET(R,I,S$) ! WHERE R IS ON THE SCREEN ROW 20 IF S$=RPT$(" ",10) THEN 100 ! TEN SPACES 30 REM THIS IS THE REST OF PROGRAM 100 REM THIS IS WHERE WE WANT TO GO This is how I would do it in RXB. But that is just me? Edited September 13, 2021 by RXB Spelling 2 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted September 13, 2021 Share Posted September 13, 2021 26 minutes ago, RXB said: This is how I would do it in RXB. But that is just me? If using RXB, I would not use RPT$() as you did, because for 10 characters the space savings is minimal (I think only one byte and only targeted toward this example,) but I also do not believe the function is any faster than a literal string. The latter, of course, would have to be tested. Otherwise, the HGET subprogram is handy but will not compile. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 13, 2021 Share Posted September 13, 2021 8 hours ago, 1980gamer said: Unfortunately any one of these conditions could be true. The lower ones are most probable at least. I think I can use a constant for the next segment of the program and that "may" help? The or vs. and was noticeable within the actual game. Complied even more so. I am doing a block of gchar's into the cls(x) values. I was calling the GCHARS on each pass. Dropping the values into the array was a huge increase in speed. But I still want to squeeze a little more out of it! ok. This makes me wonder if the compiled code would be smaller (and therefore faster) if you just summed the contents of the CLS() array in a FOR/NEXT loop. That would be like an AND on each value but I don't know if the compiler will make faster code than that inline statement. The loop overhead would be not bad in machine code. Might be worth a try. You might have to change the initial value in the array . ? Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 13, 2021 Author Share Posted September 13, 2021 (edited) 9 hours ago, TheBF said: ok. This makes me wonder if the compiled code would be smaller (and therefore faster) if you just summed the contents of the CLS() array in a FOR/NEXT loop. That would be like an AND on each value but I don't know if the compiler will make faster code than that inline statement. The loop overhead would be not bad in machine code. Might be worth a try. You might have to change the initial value in the array . ? 10 DIM CLS(20) 15 FOR X=7 TO 15 20 CLS(X)=32 25 NEXT X 30 FOR X=1 TO 1000 35 for ck=7 to 15 40 IF CLS(ck)>92 THEN END ELSE 50 45 next ck 50 NEXT X So, this seems counter intuitive to me.. Nesting the loop, meaning 9,000 more executions of for and next... However . . It is significantly faster. What did I do wrong? How can this be? HMMMMMM Edited September 13, 2021 by 1980gamer 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 13, 2021 Share Posted September 13, 2021 You would have to look at the code the compiler generates. Is that easy to see? Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 14, 2021 Share Posted September 14, 2021 2 hours ago, 1980gamer said: 10 DIM CLS(20) 15 FOR X=7 TO 15 20 CLS(X)=0 25 NEXT X 30 FOR X=1 TO 1000 35 for ck=7 to 15 40 IF CLS(ck) THEN END ELSE 50 45 next ck 50 NEXT X So you had a huge amount of code inside 1000 iteration loop. I think that was the problem. I am also wondering if the amount of code in the comparison would be less by just checking for non-zero in CLS(7) ... CLS(15) as in the BASIC code above. I just tested BASIC with this so I know the IF statement works this way in the interpreter. Don't about the compiler. 100 X=0 110 IF X THEN 120 ELSE 130 120 PRINT "TRUE" 130 PRINT "FALSE" Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 Somehow the nested loop is faster? I wish I could check for 0. 32 is a space or blank char from GCHAR. I have to all kinds of offsets etc. I am hoping some refactoring and some other clever things will speed it up. I have a series of 11 IF statements. 11580 IF CLS(COL)>92 THEN I=I+1 ELSE 11595 11581 IF CLS(COL)=93 THEN G1=G1+1 :: GOTO 11595 11582 IF CLS(COL)=101 THEN G2=G2+1 :: GOTO 11595 11583 IF CLS(COL)=109 THEN G3=G3+1 :: GOTO 11595 11584 IF CLS(COL)=117 THEN G4=G4+1 :: GOTO 11595 11585 IF CLS(COL)=125 THEN G5=G5+1 :: GOTO 11595 11586 IF CLS(COL)=95 THEN G6=G6+1 :: GOTO 11595 11587 IF CLS(COL)=103 THEN G7=G7+1 :: GOTO 11595 11588 IF CLS(COL)=111 THEN G8=G8+1 :: GOTO 11595 11589 IF CLS(COL)=119 THEN G9=G9+1 :: GOTO 11595 11590 IF CLS(COL)=127 THEN G10=G10+1 I am hoping the goto's will help the logic fall out quicker. I put them in the order that is most likely true.... At least at the start of the game. In XB I did not notice any speed change... But I am going to change the array comparison next. 11579 EE=CLS(COL) 11580 IF EE>92 THEN I=I+1 ELSE 11595 11581 IF EE=93 THEN G1=G1+1 :: GOTO 11595 11582 IF EE=101 THEN G2=G2+1 :: GOTO 11595 11583 IF EE=109 THEN G3=G3+1 :: GOTO 11595 11584 IF EE=117 THEN G4=G4+1 :: GOTO 11595 11585 IF EE=125 THEN G5=G5+1 :: GOTO 11595 11586 IF EE=95 THEN G6=G6+1 :: GOTO 11595 11587 IF EE=103 THEN G7=G7+1 :: GOTO 11595 11588 IF EE=111 THEN G8=G8+1 :: GOTO 11595 11589 IF EE=119 THEN G9=G9+1 :: GOTO 11595 11590 IF EE=127 THEN G10=G10+1 At the very least, it saves a few bytes. Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted September 14, 2021 Share Posted September 14, 2021 Take these with a grain of salt. There are two patterns to your value set. I used these two sets to calculate two ON GOTO statements. If you were using G as an array, I could calculate a subscript based upon those sets. This is how I would program what you have given. For compilation I would have to figure up a little more as numbers can only be integers and the check I make at 11580 and 11581 would always pass. 11579 EE=CLS(COL) :: IF EE>92 AND EE<128 THEN I=I+1 ELSE 11595 ! RANGE CHECK HERE 11580 E1=(EE-85)/8 :: IF INT(E1)=E1 THEN ON E1 GOTO 11582,11583,11584,11585,11586 11581 E1=(EE-87)/8 :: IF INT(E1)=E1 THEN ON E1 GOTO 11587,11588,11589,11590,11591 :: ELSE 11595 11582 G1=G1+1 :: GOTO 11595 11583 G2=G2+1 :: GOTO 11595 11584 G3=G3+1 :: GOTO 11595 11585 G4=G4+1 :: GOTO 11595 11586 G5=G5+1 :: GOTO 11595 11587 G6=G6+1 :: GOTO 11595 11588 G7=G7+1 :: GOTO 11595 11589 G8=G8+1 :: GOTO 11595 11590 G9=G9+1 :: GOTO 11595 11591 G10=G10+1 11595 ! THIS IS THE TARGET I dunno. I got crazy here, too. Another option, if using G() instead of G1..G10, assuming G() is DIMmed G(10): 11579 EE=CLS(COL) :: IF EE>92 AND EE<128 THEN I=I+1 :: ELSE 11595 ! RANGE CHECK HERE 11580 FOR E1=1 TO 10 :: IF EE=85+8*(E1+5*(E1>5))-2*(E1>5) THEN G(E1)=G(E1)+1 11581 NEXT E1 11595 ! THIS IS THE TARGET The EE formula can probably be optimized, too. I am probably just being cheeky at this point. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 14, 2021 Share Posted September 14, 2021 (edited) I don't see the big picture yet, but it looks like you are trying to find a faster way to read 10 consecutive bytes from the screen and see if they are all spaces. If so, this will work and can be compiled: CALL LINK("VREAD",vdpaddress,10,A$)::IF A$=" " THEN GO SOMEWHERE (XB256 is needed here.) From the manual: CALL LINK(“VREAD”, memory address, # bytes, string[ , . . .]) VREAD reads the specified number of bytes from the VDP ram into a string variable of up to 255 bytes. Up to 5 strings can read with one call to VREAD. Edited September 14, 2021 by senior_falcon 3 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 35 minutes ago, OLD CS1 said: 11579 EE=CLS(COL) :: IF EE>92 AND EE<128 THEN I=I+1 :: ELSE 11595 ! RANGE CHECK HERE 11580 FOR E1=1 TO 10 :: IF EE=85+8*(E1+5*(E1>5))-2*(E1>5) THEN G(E1)=G(E1)+1 11581 NEXT E1 11595 ! THIS IS THE TARGET I cannot wrap my head around this! LOL However, this made a very noticeable difference! 11579 EE=CLS(COL) 11580 IF EE>92 THEN I=I+1 ELSE 11595 11581 IF EE=93 THEN G1=G1+1 :: GOTO 11595 11582 IF EE=101 THEN G2=G2+1 :: GOTO 11595 I am running 10 gchars statements and this loops 10 times. Very slow! RXB has some nice GCHAR stuff, but I need to compile! 2 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 2 minutes ago, senior_falcon said: I don't see the big picture yet, but it looks like you are trying to find a faster way to read 10 consecutive bytes from the screen and see if they are all spaces. If so, this will work and can be compiled: CALL LINK("VREAD",vdpaddress,10,A$)::IF A$=" " THEN GO SOMEWHERE (XB256 is needed here.) From the manual: CALL LINK(“VREAD”, memory address, # bytes, string[ , . . .]) VREAD reads the specified number of bytes from the VDP ram into a string variable of up to 255 bytes. Up to 5 strings can read with one call to VREAD. I can try this! I am user XB256 of course! I have scrolling etc. happening! I have not used VREAD, can this take the place of GCHAR? 19000 CALL GCHAR(ROW,7,CLS(7)):: CALL GCHAR(ROW,8,CLS(8)):: CALL GCHAR(ROW,9,CLS(9))::CALL GCHAR(ROW,10,CLS(10)):: CALL GCHAR(ROW,11,CLS(11)) 19005 CALL GCHAR(ROW,12,CLS(12)):: CALL GCHAR(ROW,13,CLS(13)):: CALL GCHAR(ROW,14,CLS(14)):: CALL GCHAR(ROW,15,CLS(15)):: CALL GCHAR(ROW,16,CLS(16)) 19025 RETURN This section is certainly the slowest piece of the SCAN loop. I also do this over 10 rows. So 100 GCHAR statements! I tried more and less call gchar per line. Multiple statements for GCHAR seem faster, as I always believed. However, nesting the loop for the OR was MUCH faster! Oh, need to find the vdpaddress! Need to re-read the xb256 docs again! Way to late for tonight! Thank you all! 1 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 I tried to make a test for vread However, I get BAD ARGUMENT in 10 Can you re-write line 10 as an example for me? My intention if to replace GCHAR for the 10 statements. So stringing 5 vreads in 1 statement is the goal. But I do need 10 variables returned. Thanks for any help! 1 FOR ROW=1 TO 24 2 FOR COL=1 TO 32 10 CALL LINK(VREAD,((ROW-1)*32)+COL-1,1,A1$) 20 DISPLAY AT(12,16):A1$ 30 NEXT COL 40 NEXT ROW 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 14, 2021 Share Posted September 14, 2021 1 hour ago, 1980gamer said: 10 CALL LINK(VREAD,((ROW-1)*32)+COL-1,1,A1$) Try: 10 CALL LINK("VREAD",ROW*32+COL-33,1,A1$) Remember that you can read more than one byte into the string: 10 CALL LINK("VREAD",ROW*32+COL-33,10,A1$) 1 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 52 minutes ago, senior_falcon said: Try: 10 CALL LINK("VREAD",ROW*32+COL-33,1,A1$) Remember that you can read more than one byte into the string: 10 CALL LINK("VREAD",ROW*32+COL-33,10,A1$) Thank you! I know I can read more than 1 value, and I will try this as a replacement to the IF CLA(7) and CLS(8).... However, this was an attempt at replacing GCHAR. If I read the 10 chars in a string, I would still need to parse the string. A little background, I have items on a row. If items are matched in any connecting fashion, they are removed. Where S is a SPACE char(32) row 1 "AACCABSSSS" row 2 "ABSSSSSSSS" row 3 "SSSSSSSSSS" row 4 "BCABBSSSSS" Row 3 Col 1 is replaced with an A row 1 "AACCABSSSS" row 2 "ABSSSSSSSS" row 3 "ASSSSSSSSS" row 4 "BCABBSSSSS" Result: X replaces the Matching A's row 1 "XXCCABSSSS" row 2 "XBSSSSSSSS" row 3 "XSSSSSSSSS" row 4 "BCABBSSSSS" After Scan: The Rows of remaining chars are shifted to the left. It can be several rows and columns impacted. It can leave multiple space gaps row 1 "CCABSSSSSS" row 2 "BSSSSSSSSS" row 3 "SSSSSSSSSS" <-- If the next scan comes around, I do not need to loop through this row! This is were the And or Or came about. row 4 "BCABBSSSSS" So I currently read a row at a time and place the 10 values into an array. I then loop through the array looing for the first Non-SPACE char and place that into another array and move on to the NEXT non-Space char. S=Space This in SSASAABBCS Output AAABBCSSSS During this "looping" I am also drawing the row with HCHAR on the fly. I am also COUNTING each of these remaining chars. So this remaining row has 3 A's 2 B's and 1 C. I need to know this as my NEXT available "Piece" has to be a char that is on the play field. I don't want a D as the Next Piece. The loop is pretty tight now. The bottle neck is the GCHAR Up to 100 of them per playfield scan. If I can read 5 values in one read, I can cut this to 20 reads! OMG, that would make this work very well! Tonight, I will test the VREAD. I also don't understand the multiple reads per call? Is it to 5 different variables? Not talking about reading a string of 5 chars. But 5 distinct Values. I currently do not cascade the playfield.... But if this was fast enough I would consider it. Bejeweled style. Though I never intended to do that. It could be an option. 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 14, 2021 Share Posted September 14, 2021 46 minutes ago, 1980gamer said: Tonight, I will test the VREAD. I also don't understand the multiple reads per call? Is it to 5 different variables? Not talking about reading a string of 5 chars. But 5 distinct Values. CALL LINK("VREAD",0,16,A$,32,16,B$,64,16,C$,96,16,D$,128,16,E$) will read 16 bytes from screen position 0 (row 1,col 1) to A$, 16 bytes from screen position 32 (row 2,col 1) to B$, 16 bytes from screen position 64 (row 3,col 1) to C$, and so on for D$ and E$ 2 Quote Link to comment Share on other sites More sharing options...
1980gamer Posted September 14, 2021 Author Share Posted September 14, 2021 18 minutes ago, senior_falcon said: CALL LINK("VREAD",0,16,A$,32,16,B$,64,16,C$,96,16,D$,128,16,E$) will read 16 bytes from screen position 0 (row 1,col 1) to A$, 16 bytes from screen position 32 (row 2,col 1) to B$, 16 bytes from screen position 64 (row 3,col 1) to C$, and so on for D$ and E$ This is awesome! I can't wait to try it! Quote Link to comment Share on other sites More sharing options...
RXB Posted September 14, 2021 Share Posted September 14, 2021 WOW all this effort to make XB fit into a faster emulator is exactly the opposite of the language BASIC in first place! Beginners All-purpose Symbolic Instruction Code This has become so specialized it is funny. The entire reason for BASIC and XB was to keep it simple stupid. Now it is more like a another version of Assembly. Quote Link to comment Share on other sites More sharing options...
RXB Posted September 14, 2021 Share Posted September 14, 2021 (edited) 55 minutes ago, 1980gamer said: This is awesome! I can't wait to try it! RXB has CALL HGET(ROW,COL,16,A$) ! The 16 is number of bytes to read from screen into A$ this does exactly what CALL LINK("VREAD",0,16,A$,32,16,B$,64,16,C$,96,16,D$,128,16,E$) does but in a single string variable. Or you could use RXB CALL MOVES("V$",16,0,A$) ! Same result as CALL HGET but not specifically designed for this use as address is used instead of ROW,COL If RXB was converted into XB256 it would eliminate a ton of these weird lines needed to created in emulation of XB or Basic. RXB has been around since 1991 so not like it is not known or new as it is over 20 years old now. Not to mention updated and debugged! Edited September 14, 2021 by RXB missing text Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted September 14, 2021 Share Posted September 14, 2021 1 hour ago, RXB said: This has become so specialized it is funny. The entire reason for BASIC and XB was to keep it simple stupid. Now it is more like a another version of Assembly. Truth, but at the same time, for better or for worse*, it allows people comfortable with a particular level of programming to write far more capable programs. * There are plenty of good arguments, on both sides, on whether BASIC should have ever been used as a teaching tool or continue as a viable programming language. Some people will say that something like Pascal is a better starter language, while others think C or C++, among other alternatives including assembler. I have to admit that programming in BASIC got me locked into some bad habits, and Pascal was far better for me. I moved on to 9900 and 6502 (more of the latter, honestly,) and have often lamented that my first TI programming book was not the Editor/Assembler. 2 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.