4 ms·
Its always about making the right judgement call between optimization and complexity, and sometimes I'm still surprised by what needs optimized and what doesn't
by jdblair 10y ago
Its always about making the right judgement call between optimization and complexity, and sometimes I'm still surprised by what needs optimized and what doesn't.
An anecdote from a project I'm working on. I'm writing some LED control software for light shows and using GPIO pins on various embedded Linux boards (CHiP, Raspberry Pi, Orange Pi) to generate the SPIO-like serial signal I need.
My first draft, for Raspberry Pi 3, is a wonder of compact bit twiddling, doing all the necessary operations to write to GPIO memory in one compact function.
For the second platform, the Orange Pi Zero, I found a Python library for GPIO access that someone had already written, saw that the gpio operations were broken out into separate files and pulled those files into my project. My first thought: this will never be fast enough, and the O-Pi Zero is slower than the R-Pi 3. Luckily, I decided to try it first.
Now the the gory details of writing to memory are hidden in the library and the logic in my code to generate clock pulses and write bits is a lot more clear. I had to tune the code differently - the delays in my code to generate the correct clock pulse width are shorter now that there is function call overhead, but that was easy to sort out with a bit of trial-and-error with a logic analyzer.
- jdblair 10y agoSomething else I've learned the hard way - sometimes its better to cut and paste the same short code snippet in multiple places than create an abstraction to put the code in one place. I admit this is probably an indication there's a problem in the overall design, but sometimes those design choices have already been made and the goal is to make things work with what I have.
- jfim 10y ago> Something else I've learned the hard way - sometimes its better to cut and paste the same short code snippet in multiple places than create an abstraction to put the code in one place. It's a pretty short term optimization though. Sure, it'll get you working, but working on a code base with no duplication means that once you find a bug and fix it, you don't need to hunt for duplicates to fix. It also means that if you're debugging something, you know exactly which code path was taken instead of "oh I thought it using X but it's using slightly different Y." Whether that's a good trade off or not really depends on how long this code will be maintained. If it's front end glue code that will be tossed out when the CEO decides in nine months that the website should use X technology instead, then yeah, that's a fair trade off. Much less so if you know this code will be there 5-10 years down the line.
- dahart 10y ago> I'm still surprised by what needs optimized and what doesn't. Yes! Exactly. I'm almost always surprised. And it's really important to remember what benefits you get from the unoptimized code too. Once I wrote a controller input system in a game engine, the code that monitors and reacts to all the buttons on an xbox controller, for example. I spent a whole bunch of time making sure that when I hit X, the reaction code would trigger with almost no overhead at all. It did fancy stuff like watch for combos and sequences, and game designers could author the control schemes, and I spent a lot of time making sure that actions cost no CPU time. Then one day I profiled it carefully and found out that the bottleneck was something I'd forgotten to check for -- the case when no buttons were being used. The case that is happening during 99.5% of frames. The loop to check if something needed to be done had a pretty bad memory access pattern than was missing cache most of the time. I thought it would be close to a no-op, but it wasn't. I had to refactor the whole thing and flip it inside out, and I realized I'd wasted a bunch of dev time fixing the code that reacts to one button at a time. It doesn't matter how slow a single action is, because it'll never show up in the profile. It does matter if I waste a few hundred thousand cycles traipsing through memory missing cache with every instruction.