3 ms·
Random question (genuine, I do not know if it's possible): > I decided to have each particle be represented by 4 numbers an x, y, dx, and dy. These will each b
by franciscop 2y ago
Random question (genuine, I do not know if it's possible):
> I decided to have each particle be represented by 4 numbers an x, y, dx, and dy. These will each be 32-bit floating point numbers.
Would it be possible to encode this data into a single JS number (53-bit number, given that MAX_SAFE_INTEGER is 2^53 - 1 = 9,007,199,254,740,991). Or -3.4e38 to 3.4e38, which is the range of the Float32Array used in the blog.
For example, I understand for the screen position you might have a 1000x1000 canvas, which can be represented with 0-1,000,000 numbers. Even if we add 10 sub-pixel divisions, that's still 100,000,000, which still fits very comfortably within JS.
Similar for speed (dx, dy), I see you are doing "(Math.random()*2-1)*10" for calculating the speed, which should go from -10,+10 with arbitrary decimal accuracy, but I wonder if limiting it to 1 decimal would be enough for the simulation, which would be [-10.0, +10.0] and can also be converted to the -100,+100 range in integers. Which needs 10,000 numbers to represent all of the possible values.
If you put both of those together, that gives 10,000 * 100,000,000 = 1,000,000,000,000 (1T) numbers needed to represent the particles, which still fits within JS' MAX_SAFE_INTEGER. So it seems you might be able to fit all of the data for a single particle within a single MAX_SAFE_INTEGER or a single Float32Array element? Then you don't need the stride and can be a lot more sure about data consistency.
It might be that the encoding/decoding of the data into a single number is slower than the savings in memory and so it's totally not worth it though, which I don't know.
- DrMiaow 2y agoAs you stated, Encoding/decoding would kill your performance. Float16Array would immediately halve your memory requirements Another possibility would be to have separate precision arrays. eg. Float16Array for x,y and even Int8Array for dx/dy, but, in both cases you will would get some motion artifacts, especially for Int8 from the clamping and aliasing of dx/dy.
- dleeftink 2y agoYou may be interested in bitfields and JS optimised vector operations, the @thi.ng universe has some useful implementations (also a WASM simd one): [0]: https://github.com/thi-ng/umbrella/tree/develop/packages/vectors#basic-usage https://github.com/thi-ng/umbrella/tree/develop/packages/vec... [1]: https://github.com/thi-ng/umbrella/tree/develop/packages/vector-pools#api https://github.com/thi-ng/umbrella/tree/develop/packages/vec... [2]: https://github.com/thi-ng/umbrella/tree/develop/packages/bitfield#api https://github.com/thi-ng/umbrella/tree/develop/packages/bit... [3]: https://github.com/thi-ng/umbrella/tree/develop/packages/simd#api https://github.com/thi-ng/umbrella/tree/develop/packages/sim... There's also Structura, which implements a few performant data structures: [4]: https://github.com/zandaqo/structurae/blob/master/README.md#bitarray https://github.com/zandaqo/structurae/blob/master/README.md#...
- dleeftink 2y agoI also did some experimenting with number packing and ended up creating a QuickSet implementation[0]. However, it turned out that operating on TypedArrays proved more performant, which I settled on in the end. I've collected some related packages here: [0]: https://github.com/dleeftink/QuickSet https://github.com/dleeftink/QuickSet [1]: https://github.com/dleeftink/QuickSet?tab=readme-ov-file#see-also https://github.com/dleeftink/QuickSet?tab=readme-ov-file#see... Of note is FastIntSet, which uses the technique you described, but I think is only able to store 4 unsigned integers as one JS value (I might be wrong). [2]: https://github.com/TheLucifurry/fast-int-set/blob/main/src/sets/uintSet.ts https://github.com/TheLucifurry/fast-int-set/blob/main/src/s... This notebook demonstrate a MVP bitpacking technique using BigInts (see the 'bitpack' and 'pack' cells): [3]: https://observablehq.com/@dleeftink/array-bitbuffers https://observablehq.com/@dleeftink/array-bitbuffers SimSIMD offers various similarity measures and quantisation levels for TypedArrays: [4]: https://github.com/ashvardanian/simsimd#using-simsimd-in-javascript https://github.com/ashvardanian/simsimd#using-simsimd-in-jav...