Moon phases

An experiment with per-pixel shading using a grayscale palette and dithering:

It’s a bit slow on hardware (maybe 4 frames/s), and that’s after a speedup attempt, you can see my previous slower drawing method by holding down the A button.

10 Likes

I was able to increase the frame rate using fixed point math. It run smootly on a PyBadge

5 Likes

Very interesting, thanks! I thought the PyGamer CPU had direct floating point support, so I’m surprised that the mostly-integer version is that much faster. You had even kept the floating point square root which I had been suspicious about. I’ll experiment some more along these lines, this may need some microbenchmarks to figure out the low-level performance.

This research paper has more background about the internals: https://www.microsoft.com/en-us/research/uploads/prod/2019/09/mplr19main-id10-p-41a6cf2-42682-final.pdf

Apparently one problem is that Javascript requires the Number type to be a double-precision (64-bit) floating point number, and if the hardware only supports single-precision (32-bit) floats, that isn’t usable for numeric operations:

The FPU on the M4F cores is only single-precision, so it was not used in benchmarks. [Page 8]

If I’m understanding it right, the runtime uses dynamic typing with tagged values where 31-bit integers use a fast path, while other values get handled by slower software routines. Interestingly, Math.imul isn’t quite good enough to ensure this restriction is met since that assumes 32-bit integers, so the result of that could still overflow into a slow float value, but in this specific case the result won’t get large enough for that to matter.