DanielSant0s / AthenaEnv

A complete Javascript environment for creating homebrew applications and games on PlayStation 2.
GNU General Public License v3.0
156 stars 20 forks source link

[QUESTION] Alternative to `f` suffix on single floats #24

Closed arthurdenner closed 1 year ago

arthurdenner commented 1 year ago

From the README:

This project introduces a (old)new data type for JavaScript: single floats. Despite being less accurate than the classic doubles for number semantics, they are important for performance on the PS2, as the console only processes 32-bit floats on its FPU. You can write single floats on AthenaEnv following the syntax below:

let test_float = 15.0f; // The 'f' suffix makes QuickJS recognizes it as a single float.

While I get the reason behind it, I'd like to mention that this approach breaks JavaScript tools such as ESLint and Prettier.

Of course, these tools are not critical but it'd be nice to have them (and possibly others like TypeScript) supported like in any other JavaScript project. I Google'd a bit and discovered the Math.fround method, which:

returns the nearest 32-bit single precision float representation of a number

In the same page, it mentions that:

JavaScript continues to treat the number as a 64-bit float, it just performs a "round to even" on the 23rd bit of the mantissa, and sets all following mantissa bits to 0.

As I'm not so familiar with single floats and lower-level languages, I was wondering if you have explored this approach as a replacement for the f suffix and if there are any drawbacks.

I tried using this method in the dashboard and pong files which then could be formatted by Prettier for example. I didn't see an increase of memory usage but as the demos are simple, that's probably not a valid test case.

DanielSant0s commented 1 year ago

The main reason why I implemented real single floats (which directly use single floats on the C side and not clipped doubles) is that the PlayStation 2 is unable to process doubles by hardware, it needs to use software functions, which ends up causing considerable losses when dealing with tens or hundreds of floats in a loop.

For instance

Rendering with double floats: image

Rendering with single floats: image

I got more 5 FPS, and my code sample use a few floats, imagine that difference from hundreds.

I tried exploring Math.fround returning real singles. But I didn't like to create a double and after that cutting it into a single, I can have more performance just creating singles from the variable declaration.

DanielSant0s commented 1 year ago

I can edit Math.fround to return real singles, so you can handle with Float32 type without breaking format extensions, I think that's a fair solution, what do you think about it?

arthurdenner commented 1 year ago

I think it's a fair tradeoff since it's a specific runtime, I like the idea 👍🏽

emersonlaurentino commented 1 year ago

@DanielSant0s if every decimal number must be in 32bits, why not always convert to single? This would avoid using the math API or f suffix.

DanielSant0s commented 1 year ago

It breaks numbers semantics

DanielSant0s commented 1 year ago

@arthurdenner I finished Math.fround implement. https://github.com/DanielSant0s/AthenaEnv/commit/792b7332bb36a3597bcef3900516abc5a5d00e8a

arthurdenner commented 1 year ago

That's really good news. Thanks for the update!