When writing assembly for the TI-83 Plus or TI-84 Plus CE, what is a general rule of thumb for whether to optimize for speed vs size, if at all. From what I understand, you should try to optimize for size when possible and only optimize for speed when it is too slow, but I don't know when not to apply it, especially for the CE, where it is wayyy faster and has a lot more RAM than the 83+.

For reference, the TI-83 Plus has 32 KiB of RAM with a 6 MHz Zilog Z80, and the TI-84 Plus CE has 256 KiB of RAM running a 48 MHz eZ80 with wait states.
I think it depends a lot on what type of program it is. If it's a game you might want to hit a particular frame rate target, in which case you should optimize for speed until you hit that target and then optimize for size.

For code that doesn't run in a loop, speed often isn't important, so it makes sense to optimize for size.

Library routines are a bit harder because you have to anticipate the needs of the library's users. In general I think it makes sense to optimize for speed up to a certain point, since you don't know what kind of performance requirements the user has. It's usually better to use a more efficient algorithm that's slightly more complicated and therefore larger, but taking that to an extreme and turning a routine into a constant-time lookup in an enormous table usually isn't a great idea. A lot of the time there's a pretty obvious point where the additional size isn't worth it (e.g. going from peephole speed optimizations to "oh, I can save a few cycles by sticking ten different copies of this code in here").

In some cases, where the speed-size tradeoff is particularly extreme, it might be best to just write two different implementations of the routine and let the user pick the one that better fits their requirements.

But really for a lot of non-library projects I feel like it makes the most sense to optimize for maintainability. There's often a point where a program is "fast enough." There's also a decent amount of flash on the calculator compared to the maximum size of a program. And heavily optimizing a program for either size or speed makes it a lot harder to make changes to the program in the future.

I made that mistake with a few of my projects. In Tanks!, I optimized a lot of the graphics code before I had finished implementing all the functionality I wanted, switching to a really convoluted system that involved doing partial redraw with gfx_SwapDraw by copying regions of the screen into memory. When I went to add the last few features, like mine explosions and the pause menu, I realized that that approach wouldn't work for them, and that I would have to undo a lot of the graphics optimizations that I did. I ended up just kinda dropping the project instead of rewriting everything that touched graphics code.
What's bad are the extremes, as indicated by commandblockguy. In fact, that often goes beyond optimization of computer programs, but that's an unrelated topic we really shall not pursue here Smile

On the TI-68k series, I've witnessed a number of times extreme speed optimization blowing size and/or memory consumption out of any reasonable proportion (e.g. with preshifted sprites, gotta really need them...), or extreme size optimization having significantly negative speed impact, e.g. because of multiplication or division instructions being introduced in situations where few enough shift, add and sub instructions are faster.

One of the few areas where people have historically tolerated a significantly unrolled loop was the software grayscale routine ( https://github.com/debrouxl/gcc4ti/blob/experimental/trunk/tigcc/archive/gray.s below label __gray_perform_copying, that's the late version which even uses the stack pointer as data register since that part of the code has always run with all interrupts disabled anyway), since any cycle wasted there is taken from cycles usable for user programs. Too bad I did not realize much earlier that the rest of this software grayscale code was ripe for size optimization even in the absence of a memory consumption optimization for old calculator models...
However, for the likes of https://github.com/debrouxl/ExtGraph/blob/master/src/lib/Misc/FastCopyScreen.s , it makes no sense to make the routine nearly 10x larger by fully unrolling the loop instead of copying a 10th of the screen size 10 times: the speed cost of copying with 1 fewer register because of the counter, and branching, is almost negligible.
To add on this, a good rule of thumb is to optimize the most executed code (tight loop, frequently used routines) for speed, and the rest for size. Of course, if the performance you want is already reached without speed optimization, optimizing for size is a good option.
And the extreme... well, that's also the fun part of assembly Razz
I think it's good, also, to keep in mind the famous Donald Knuth quote:
Donald Knuth wrote:
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.


And to take a line from Wiki:
Quote:
Human beings, even experienced programmers, are very poor at predicting (guessing) where a computation will bog down.


If you hyper-focus on optimization, you might not ever get your program finished. You should, of course, design things efficiently so you don't have to re-design around performance if an issues crops up. But you also shouldn't spend a whole lot of time trying to optimize code you don't yet know to be a performance issue. Profile first to determine where the bottlenecks are. Once you've identified a performance issue and where it lies, you can optimize tactically.

First, your program should function. Then it should function efficiently. If the first part isn't done, there's little use in doing too much toward the second.
I would say always aim to optimise for size when coding in assembly as most of the time that gets you a good speed payoff anyway, generally (just not to the extreme). Then when you have an understanding of where you most often executed code is required, work to speed optimise that.

I like to figure out what the most speed critical parts of a routine might be an brainstorm that myself, mainly because it's fun Smile.

Either way coding and optimisation is a never ending journey. Half of it is knowing the instructions and then looking at your problem for all angles until you come up with a good solution.

The Donald Knuth quote is famous for a reason too Smile. Work on getting it working, then on making it better!
My code typically includes a LOT of loops, so I usually optimize for speed in loops and optimize mostly the variables being used for the program. It might not be the best but it works for what I do. (Mess Around)
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement