freewheel Posted December 21, 2014 Share Posted December 21, 2014 I've noticed an interesting quirk, and I'm sure the experts here will see this and say "duh!": When using SCROLL - and the offset_ syntax nanochess has in his examples - I'm noticing performance is absolutely essential to keep tabs on. Do too much work before your next SCROLL/WAIT, and you start to get jittery sprites. I suspect that doing enough "work" on the CPU causes it to get behind somewhat, so it has to eventually "catch up" and this is what causes my MOBs to occasionally jump around. A big offender? Using AND in IF statements. Example: IF a=1 AND b=2 AND c=3 THEN do_something Due to complex logic (and good old spaghetti code), I have a lot of this sort of thing going on. Well, if I convert all of these to this: IF a=1 THEN IF b=2 THEN IF c=3 THEN do_something It's remarkable how much calmer things are. MOBs don't jitter, and everything is smooth again. Intuitively my brain thinks that the latter is going to be "worse" - it sure is worse to read - but I guess it's only doing the first comparison much of the time and ignoring the rest, whereas the former example does all 3 comparisons every single time. Multiply this by a dozen or more of these kind of statements, and it's remarkable how much of an impact it has. A warning for budding IntyBASIC programmers - limit your comparisons as much as possible Is cmp really that processor intensive? Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/ Share on other sites More sharing options...
intvnut Posted December 21, 2014 Share Posted December 21, 2014 (edited) I've noticed an interesting quirk, and I'm sure the experts here will see this and say "duh!": When using SCROLL - and the offset_ syntax nanochess has in his examples - I'm noticing performance is absolutely essential to keep tabs on. Do too much work before your next SCROLL/WAIT, and you start to get jittery sprites. I suspect that doing enough "work" on the CPU causes it to get behind somewhat, so it has to eventually "catch up" and this is what causes my MOBs to occasionally jump around. A big offender? Using AND in IF statements. Example: IF a=1 AND b=2 AND c=3 THEN do_something Due to complex logic (and good old spaghetti code), I have a lot of this sort of thing going on. Well, if I convert all of these to this: IF a=1 THEN IF b=2 THEN IF c=3 THEN do_something It's remarkable how much calmer things are. MOBs don't jitter, and everything is smooth again. Intuitively my brain thinks that the latter is going to be "worse" - it sure is worse to read - but I guess it's only doing the first comparison much of the time and ignoring the rest, whereas the former example does all 3 comparisons every single time. Multiply this by a dozen or more of these kind of statements, and it's remarkable how much of an impact it has. A warning for budding IntyBASIC programmers - limit your comparisons as much as possible Is cmp really that processor intensive? Ok, so I tried a dirt simple experiment with IntyBASIC 1.0. (I haven't downloaded 1.0.1 yet.) The short answer is that IntyBASIC doesn't perform short-circuit evaluation such as what C does for && and || operators. It evaluates AND and OR more like C's & and |, neither of which imply short-circuit evaluation. Here's the simple test I ran: . if a = 1 AND b = 1 AND c = 1 then print "foo" if a = 1 then if b = 1 then if c = 1 then print "foo" . For the first IF statement, you can see IntyBASIC building up the condition in the assembly code: . ;[4] if a = 1 AND b = 1 AND c = 1 then print "foo" SRCFILE "/tmp/and.bas",4 MVI V1,R0 CMPI #1,R0 MVII #-1,R0 BEQ T2 INCR R0 T2: MVI V2,R1 CMPI #1,R1 MVII #-1,R1 BEQ T3 INCR R1 T3: ANDR R1,R0 MVI V3,R1 CMPI #1,R1 MVII #-1,R1 BEQ T4 INCR R1 T4: ANDR R1,R0 BEQ T1 MVI _screen,R4 MVII #560,R0 XOR _color,R0 MVO@ R0,R4 XORI #72,R0 MVO@ R0,R4 MVO@ R0,R4 MVO R4,_screen T1: . The code literally turns each comparison into a 0 or -1 value, and then ANDs them all together. The final result of the AND determines whether the 'THEN' or 'ELSE' condition gets evaluated. With the multiple 'if' code, you can see that each IF statement jumps out of the entire evaluation once the condition's proved false. That stops the entire comparison process as soon as one of the terms compares false: . ;[6] if a = 1 then if b = 1 then if c = 1 then print "foo" SRCFILE "/tmp/and.bas",6 MVI V1,R0 CMPI #1,R0 BNE T5 MVI V2,R0 CMPI #1,R0 BNE T7 MVI V3,R0 CMPI #1,R0 BNE T9 MVI _screen,R4 MVII #560,R0 XOR _color,R0 MVO@ R0,R4 XORI #72,R0 MVO@ R0,R4 MVO@ R0,R4 MVO R4,_screen T9: T7: T5: . Because the code isn't trying to compute the arithmetic AND of the test conditions, it also ends up being shorter overall. So that's the reason why the latter construct ends up being more efficient. Does it make sense for IntyBASIC to recognize the special case where the left-hand-side and right-hand-side of an AND or and OR are both boolean-valued expressions, and optimize it in some way? Even without short-circuiting, perhaps it could do better than it does today. Edited December 21, 2014 by intvnut 2 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137195 Share on other sites More sharing options...
freewheel Posted December 21, 2014 Author Share Posted December 21, 2014 My god, I had forgotten than C (and a ton of other languages) even did that. With so much horsepower at the table, and so much other overhead, I just don't even think of this stuff anymore. Plus I usually don't have to write so many conditionals in a single line, thanks to blocked code. The only way to simulate than in IntyBASIC is through yet another GOSUB, and that gets even more spaghetti-fied. Incidentally, I've also noticed a case where unrolling a FOR loop suffered a huge performance hit with similar effects re: MOB jitter. Not sure what he hell was going on there; I was trained that the opposite behaviour is almost entirely the case. Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137281 Share on other sites More sharing options...
intvnut Posted December 21, 2014 Share Posted December 21, 2014 (edited) My god, I had forgotten than C (and a ton of other languages) even did that. With so much horsepower at the table, and so much other overhead, I just don't even think of this stuff anymore. Plus I usually don't have to write so many conditionals in a single line, thanks to blocked code. The only way to simulate than in IntyBASIC is through yet another GOSUB, and that gets even more spaghetti-fied. Incidentally, I've also noticed a case where unrolling a FOR loop suffered a huge performance hit with similar effects re: MOB jitter. Not sure what he hell was going on there; I was trained that the opposite behaviour is almost entirely the case. That definitely seems odd. But, if your 'rolled' loop has simpler expressions than your unrolled loop, then that makes a certain amount of sense. ie. if your 'rolled' loop looks like this: . FOR I = 1 TO 10 ... do something with I NEXT I . while your unrolled loop looks like this: . FOR I = 1 TO 5 ... do something with 2*I - 1 ... do something with 2*I NEXT I . then those extra computations for 2*I - 1 and 2*I would slow you down. This is a place where fancier higher-level optimizations would help, but don't really fit IntyBASIC's line-by-line, all variables live in RAM model. Induction variable elimination, strength reduction, common subexpression elimination, register allocation (as in making a variable a purely register variable) and loop rotation all apply here. Of course, compiler loop unrolling could turn the first one into the second one for you , but that's another higher-level optimization that I'm not sure works in an IntyBASIC context. You might try benchmarking your IntyBASIC code in jzIntv's debugger. It prints cycle counts at the far right. See this post for some more details of how do enable IntyBASIC source-level debugging in jzIntv, if you haven't played with it already. You will have to peek at the IntyBASIC compiler output, though, to find the assembler labels used for two points in your code that you want to measure between. Edited December 21, 2014 by intvnut 1 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137342 Share on other sites More sharing options...
intvnut Posted December 21, 2014 Share Posted December 21, 2014 My god, I had forgotten than C (and a ton of other languages) even did that. Also, short-circuit evaluation is important to correctness in C. Consider the idiom: if ( p && p->something ). Without short-circuit evaluation, you could end up dereferencing a NULL pointer. IntyBASIC doesn't make such a guarantee, though. Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137370 Share on other sites More sharing options...
+DZ-Jay Posted December 21, 2014 Share Posted December 21, 2014 . The code literally turns each comparison into a 0 or -1 value, and then ANDs them all together. The final result of the AND determines whether the 'THEN' or 'ELSE' condition gets evaluated. Thanks for the explanation. That definitely explains the behaviour. It also elucidates why some programming languages would choose not to offer short-circuit evaluation of expressions. I always thought that short-circuit evaluation came for free, since in Assembly, you basically jump out the moment a test fails; and I always wondered why some languages like BASIC tended not to do this. Still, the code generator could be smart enough to handle it. I guess it is a lot more effort on the compiler to do so, which is why so many versions of BASIC avoid it. -dZ. Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137437 Share on other sites More sharing options...
intvnut Posted December 21, 2014 Share Posted December 21, 2014 Thanks for the explanation. That definitely explains the behaviour. It also elucidates why some programming languages would choose not to offer short-circuit evaluation of expressions. I always thought that short-circuit evaluation came for free, since in Assembly, you basically jump out the moment a test fails; and I always wondered why some languages like BASIC tended not to do this. Still, the code generator could be smart enough to handle it. I guess it is a lot more effort on the compiler to do so, which is why so many versions of BASIC avoid it. Interestingly, C has both. Short-circuit evaluation came late to the language. Originally, K&R used the same boolean operators for logical evaluation as for bitwise evaluation, which explains why the precedence of & and | is so low in C. That's also why foo & MASK == 0 is unlikely to do what you want in C. Ironically, with modern processors, short-circuit evaluation actually can hurt you, as branches are expensive (particularly mispredicted branches) but math is cheap. So, modern compilers have additional tests to determine if they can turn short-circuit operators (which require a branch) into the non-short-circuiting operators safely. For my 'guard' example above, if ( p && p->something ), it can't. But for if ( a == 3 && b == 2 ), it can. In the context of IntyBASIC, I suppose it would be possible for the compiler to detect that an entire expression is, say, a chain of ANDs or a chain of ORs on 0/-1 valued subexpressions and add short-circuit evaluation there as an optimization. Otherwise, AND and OR in IntyBASIC are bitwise operators, with all that implies. Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137442 Share on other sites More sharing options...
+DZ-Jay Posted December 21, 2014 Share Posted December 21, 2014 (edited) In the context of IntyBASIC, I suppose it would be possible for the compiler to detect that an entire expression is, say, a chain of ANDs or a chain of ORs on 0/-1 valued subexpressions and add short-circuit evaluation there as an optimization. Otherwise, AND and OR in IntyBASIC are bitwise operators, with all that implies. Or implement the VB.Net kludge: And and Or are short-circuit operators, while AndAlso and OrElse retain the non-short-circuit behaviour of VB 6.0. -dZ. Edited December 21, 2014 by DZ-Jay Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137487 Share on other sites More sharing options...
intvnut Posted December 21, 2014 Share Posted December 21, 2014 (edited) Or implement the VB.Net kludge: And and Or are short-circuit operators, while AndAlso and OrElse retain the non-short-circuit behaviour of VB 6.0. -dZ. Isn't it the other way around? And and Or are bitwise, while AndAlso / OrElse are short-circuiting. You could do the same here in IntyBASIC. That'd give you an analog to C's & vs. && and | vs. ||. Perl 6 has a short-circuiting XOR. Maybe that's going a step too far. Edited December 21, 2014 by intvnut Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137518 Share on other sites More sharing options...
freewheel Posted December 22, 2014 Author Share Posted December 22, 2014 Unless it happens soon, I hope that if nanochess re-writes the behaviour of AND/OR, that he implements new commands for the short-circuiting. Re-writing how existing syntax works can cause a whole host of fun when you re-compile. Given that I'd like to put a large body of code out there eventually, for people to learn on and such, I really don't want to have to have caveats like "this code must be compiled with version x.y.z". That shit drives me nuts. I'm already seeing subtle changes in behaviour here and there whenever IntyBASIC is updated - granted much of that is probably my fault for trying unorthodox things. To be fair, I don't see a lot of people running into what I'm seeing. An awful lot of it is just laziness, over-ambitious code being plunked into poorly-thought out frameworks, and/or spaghetti. Hm. I guess that applies to a heck of a lot of BASIC 1 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137556 Share on other sites More sharing options...
+DZ-Jay Posted December 22, 2014 Share Posted December 22, 2014 Isn't it the other way around? And and Or are bitwise, while AndAlso / OrElse are short-circuiting. You could do the same here in IntyBASIC. That'd give you an analog to C's & vs. && and | vs. ||. You are right, of course! DOH! Perl 6 has a short-circuiting XOR. Maybe that's going a step too far. Bleh. I gave up on Perl 6 right around the time the Year Of Linux On The Desktop didn't happened... 1 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137767 Share on other sites More sharing options...
freewheel Posted December 22, 2014 Author Share Posted December 22, 2014 Bleh. I gave up on Perl 6 right around the time the Year Of Linux On The Desktop didn't happened... That year was 2003 for me. Never looked back Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3137792 Share on other sites More sharing options...
intvnut Posted December 23, 2014 Share Posted December 23, 2014 (edited) That year was 2003 for me. Never looked back Wow. They hadn't even started on an implementation by then. Me? I spent an awful 2 - 3 years with Moose in anticipation that its style would help me with Perl 6. That was awful. Moose is one of those things that draws you in with all sorts of promising features, and then beats you up in a dark alley with leaky abstractions, awful performance, plausible-yet-incorrect-or-incomplete documentation and inscrutable error messages. That 2 - 3 years was about 9 months of thinking "this isn't so bad" and ~2 years of maintaining the result. Unless it happens soon, I hope that if nanochess re-writes the behaviour of AND/OR, that he implements new commands for the short-circuiting. Re-writing how existing syntax works can cause a whole host of fun when you re-compile. Given that I'd like to put a large body of code out there eventually, for people to learn on and such, I really don't want to have to have caveats like "this code must be compiled with version x.y.z". That shit drives me nuts. I'm already seeing subtle changes in behaviour here and there whenever IntyBASIC is updated - granted much of that is probably my fault for trying unorthodox things. I personally prefer having separate logical vs. bitwise booleans. Heck, I even have an almost relevant license plate on my car... Edited December 23, 2014 by intvnut 1 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3138649 Share on other sites More sharing options...
First Spear Posted January 4, 2015 Share Posted January 4, 2015 You code in VB.NET also? Is there no limit to your powers? Or implement the VB.Net kludge: And and Or are short-circuit operators, while AndAlso and OrElse retain the non-short-circuit behaviour of VB 6.0. -dZ. Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3145556 Share on other sites More sharing options...
+DZ-Jay Posted January 4, 2015 Share Posted January 4, 2015 (edited) You code in VB.NET also? Is there no limit to your powers? I got "stuck" on a stint doing VB.NET for a while. I think VB.NET is a big improvement on old VB, but that's like saying pulling off your fingernails is preferable to chopping up an arm. I much prefer C# as an expressive language overall, though I hate the .NET framework implementation. All told, I think I've programmed in over 20 distinct languages, including scripting, database, and systems development languages, in as many platforms; but I've excelled on probably less than half, and truly mastered only a handful that I really enjoyed. Traditionally, my languages of choice have been C for UNIXy things, Pascal/Delphi for DOS/Windowy things, and Perl for playing around. I find the expressiveness of Perl (and its style and philosophy) to match closely the way I think. And Pascal, because it was the first "real" language I used when I "graduated" from BASIC (not counting 6210 Assembly); so it now holds a special place in my heart. All that said, as much as I hate VB.NET, and as much as I love Delphi, there is nothing -- NOTHING -- on Hell or Earth that can inflict such utter, excruciating agony as that wretched, demonic spawn known as Delphi.Net. Ugh, I shudder just to think about it. Thankfully, I moved away from software development a few years ago, so I do my coding for fun now--such as it is. -dZ. Edited January 4, 2015 by DZ-Jay 2 Quote Link to comment https://forums.atariage.com/topic/232968-intybasic-then-if-vs-and-and-performance/#findComment-3145800 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.