You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Float32x4 should have a constructor for int values #46182
Since it's very common to have operations between int and double, Float32x4 should also have a specialized constructor for int values. With that will be possible to have an optimized version of the constructor that is capable to efficiently instantiate a Float32x4 usingint values, avoiding 4 calls to i.toDouble().
Also a toInt32x4() method should exists, to have an efficient way to convert a x4 lane of double to int (Int32x4).
The same pattern should exists for Int32x4, a double constructor and a toFloat32x4 method.
This specialized constructors and methods are very important to use SIMD in a real world solution.
Would it be sufficient to have toInt32x4 on Float32x4 and toFloat32x4 on Int32x4?
Then instead of Float32x4.fromInts(a, b, c, d), you'd do Int32x4(a, b, c, d).toFloat32x4().
It feels like that would match the actual underlying SIMD operations.
I think that the constructor is need (Float32x4.fromInts(a, b, c, d)), since the point here is performance, and will be slower to crate a Int32x4 and after that create the Float32x4.
Note that toInt32x4 on Float32x4 and toFloat32x4 on Int32x4 are also needed, to avoid any overhead for a complex SIMD computation.
A properly SIMD optimized Int32x4(a, b, c, d).toFloat32x4() seems like it could, and should, be as fast as possible.
The allocation of the Float32x4 can be eliminated, and the four integers stored directly into a SIMD register, then the SIMD "int to float" operation (CVTDQ2PS IIRC) can work directly on that. Whether to box the result as a Float32x4 at that point depends on what you plan to use it for.
@gmpassos we don't target WASM, so we can't right now make use of these APIs anyway. (in other words if you target JS today you get really poor performance from Dart SIMD types). If we would target WASM - there would be an optimization step which would produce the most optimal sequence of commands. Looking at the spec (https://github.com/WebAssembly/simd/blob/main/proposals/simd/SIMD.md) it seems that it would likely require creating a SIMD value and then converting it - just like on x86 and ARM CPUs.
WASM, or any target assembly language, should not affect the concept of object constructors.
If you need to instantiate a 'Int32x4' to have a 'Float32x4' from 4 'int' you will miss the opportunity to avoid an extra allocation. A good acceleration by SIMD should always skip any overhead.
I plan to look into this. I think the main question is whether we should have
<SIMD_TYPE>.asX()
or
factory <SIMD_TYPE>.fromX(...)
Or perhaps we should just have a shared interface between all SIMD types and have .asX() as a static extension so we don't pay for 8x8, but just 8 (... in the limit, once we have all possible SIMD types).
Activity
lrhn commentedon May 31, 2021
Would it be sufficient to have
toInt32x4onFloat32x4andtoFloat32x4onInt32x4?Then instead of
Float32x4.fromInts(a, b, c, d), you'd doInt32x4(a, b, c, d).toFloat32x4().It feels like that would match the actual underlying SIMD operations.
gmpassos commentedon Jun 1, 2021
I think that the constructor is need (
Float32x4.fromInts(a, b, c, d)), since the point here is performance, and will be slower to crate aInt32x4and after that create theFloat32x4.Note that
toInt32x4on Float32x4 andtoFloat32x4onInt32x4are also needed, to avoid any overhead for a complex SIMD computation.lrhn commentedon Jun 1, 2021
A properly SIMD optimized
Int32x4(a, b, c, d).toFloat32x4()seems like it could, and should, be as fast as possible.The allocation of the
Float32x4can be eliminated, and the four integers stored directly into a SIMD register, then the SIMD "int to float" operation (CVTDQ2PSIIRC) can work directly on that. Whether to box the result as aFloat32x4at that point depends on what you plan to use it for.gmpassos commentedon Jun 1, 2021
You are correct for Dart native implementation of SIMD (Dart VM/AOT).
For other platforms, like JS/Web, maybe the languages needs an easy and explicit way to allow the correct translation/conversion.
https://github.com/WebAssembly/simd
Note that Chrome 91 (recently released), have enabled JS SIMD by default:
https://www.chromestatus.com/feature/6533147810332672
See the end of the thread:
https://bugs.chromium.org/p/v8/issues/detail?id=6020&desc=2
mraleph commentedon Jun 1, 2021
@gmpassos we don't target WASM, so we can't right now make use of these APIs anyway. (in other words if you target JS today you get really poor performance from Dart SIMD types). If we would target WASM - there would be an optimization step which would produce the most optimal sequence of commands. Looking at the spec (https://github.com/WebAssembly/simd/blob/main/proposals/simd/SIMD.md) it seems that it would likely require creating a SIMD value and then converting it - just like on x86 and ARM CPUs.
gmpassos commentedon Jun 1, 2021
A language definition should also target the future.
lrhn commentedon Jun 2, 2021
Indeed, and preparing for WASM SIMD would mean favoring conversion methods over constructors. WASM doesn't have constructors at all, after all.
gmpassos commentedon Jun 2, 2021
WASM, or any target assembly language, should not affect the concept of object constructors.
If you need to instantiate a 'Int32x4' to have a 'Float32x4' from 4 'int' you will miss the opportunity to avoid an extra allocation. A good acceleration by SIMD should always skip any overhead.
mraleph commentedon Jun 2, 2021
There will be no allocation after this
Int32x4(a, b, c, d).toFloat32x4()is compiled by optimising compiler.gmpassos commentedon Jun 15, 2022
How about the
toInt32x4?Note that
Float32x4.fromInt32x4Bitsis not the same thing:https://api.flutter.dev/flutter/dart-typed_data/Float32x4/Float32x4.fromInt32x4Bits.html
modulovalue commentedon Jul 20, 2026
I plan to look into this. I think the main question is whether we should have
<SIMD_TYPE>.asX()or
factory <SIMD_TYPE>.fromX(...)Or perhaps we should just have a shared interface between all SIMD types and have
.asX()as a static extension so we don't pay for 8x8, but just 8 (... in the limit, once we have all possible SIMD types).