19 ms·
What’s the motivation for optimising this? If it’s for user input, you only need to call this once per frame (or at most a few times).
by iainmerrick 4y ago
What’s the motivation for optimising this? If it’s for user input, you only need to call this once per frame (or at most a few times).
- beckingz 4y agofaster parsing of user input means more time for doing graphics and game state! Though in this case 1.5 nanoseconds vs 40 nanoseconds is small and won't matter for most games.
- Cthulhu_ 4y agoMore faster is more better; you only have 16 milliseconds per tick assuming you want to read input 60 times a second, some games poll even faster / have a higher frame rate.
- nmilo 4y agoIt's still a difference of 38.5 nano seconds. You have a budget 16,000,000 nanoseconds per frame. It's like Jeff Bezos writing about how to save money at Walmart; just pick the readable and stupid approach and move on. Game loops are made fast or slow by the efficiency of their tight loops: the render loop, physics update loop, UI loop, etc. Something that happens once per frame is barely ever worth considering.
- GeoKureli 4y agoAgreed, 35ns x4 times per frame is less important than readability.
- sgtnoodle 4y agoOk, but 40ns of 16ms is 0.00025% of your frame time.
- dahart 4y agoIt doesn’t matter for user input, the 40ns won’t make a difference even at 60fps or higher with 4 players. (Have written the controller processing loop for a console game engine.) I suspect it would be less than 40ns if float was used instead of double; there’s no good reason to use double here at all. But the proposed solution is better, and super easy (arguably easier than atan2+sincos), so maybe no reason not to use it a save a few microseconds if it happens to add up to that much. I could imagine other uses of this code, like a UI wind map, or some kind of randomized maze, or something else. There might be reasons to round a vector of directions all at once.
- iainmerrick 4y agoYeah, it’s a cute optimisation, and might make sense in a game engine; I just question whether this would ever be worthwhile writing as custom code in a single game. I’m not sure I agree it’s more readable. The optimised version is reasonably regular, but it’s still longer and has more constants, hence more opportunities for sign errors and the like. It feels sort of like jumping through hoops to avoid a matrix inversion, say. Sure, matrix inversion is “slow”, but unless you’re doing it millions of times a frame it doesn’t remotely matter. If matrix inversion or atan2 is the most direct way to express a transformation, just do it that way.
- dahart 4y agoI think the atan2+sincos version is more readable, so I guess we actually do agree there. But I wouldn’t (and didn’t) use that in a game engine. For rounding and readability in a real engine, I’d name 4 of the 8 directions and look for the largest absolute value dot product. That would at least corral the constants. And I’d use (did use) f16 or integer arithmetic. One reason I have to support this kind of optimization and not reach for the trig method by default is the last time I wrote a controller system, it wasn’t limited to something as small as deciding on a single dpad-like direction, it was a much larger system that designers could author controller recognizers for, up to and including drawing shapes like a circle with the stick, or entering a time based sequence of inputs (think Contra’s famous up-down-up-down-etc-etc cheat code). If you have sequences and multiple players and high frame rate and many possible patterns to identify, that’s when efficiency of these small operations really starts to add up. I actually spent the most development time ensuring that the amount of time spent not recognizing controls was minimized, making sure that a no-op pass through the system was measured in nanoseconds and not microseconds.
- jesse__ 4y agoI can think of a few reasons: 1. writing a game that movement happens along 8 axes, and needs to trace lots of rays 2. several other reasons similar to (1) 3. had a clever idea to optimize a thing and went ham, for fun