Open wihrl opened 1 year ago
Can you reproduce this in 3.5.1 which uses Mono?
System.Numerics
uses intrinsics so it's expected it would be faster.
We could probably use SIMD to speed things up a bit, note that SIMD is also not implemented on the C++ side of the engine, there is a proposal for that https://github.com/godotengine/godot-proposals/issues/4563 but it likely won't affect C# since we reimplement the math in order to avoid marshaling.
If you really need the performance, there's nothing wrong about converting your inputs into System.Numerics
types to perform the math operations and then convert back to Godot
types to return the output.
Happy to provide input here and/or recommendations for implementation (whether for C/C++ or C#).
Recently completed a large multi-release refactoring of the general backing JIT code for System.Numerics and a more general rewrite of Matrix3x2 and Matrix4x4 for .NET 8 that resulted in up to 48x faster code for some APIs and of course that's all MIT as well so shouldn't be overly complicated to port to godot if necessary.
Edit: For those unaware, I'm the owner of the System.Numerics and System.Runtime.Intrinsics namespaces on the .NET libraries team. Love what's been going on in godot land and congrats on the 4.0 release!
I'm taking a look at this as part of #79395.
I have a suite of benchmarks that compares:
Summary:
@tannergooding I'll contact you if these problems are not solved with next preview (or RC). Thanks.
Results: (example ported to C#, 512x512px) https://github.com/godotengine/godot/blob/725beaa7afce294f38d4aca1fa287249021b6bf8/core/io/image.cpp#L3646-L3692 | Namespace | Method | Runtime | Mean | Error | Ratio | Code Size |
---|---|---|---|---|---|---|---|
Godot_Old | BumpToNormal | .NET 6.0 | 4.750 ms | NA | 1.00 | 735 B | |
Godot_New | BumpToNormal | .NET 6.0 | 3.593 ms | NA | 0.76 | 500 B | |
SnVec_Struct | BumpToNormal | .NET 6.0 | 4.143 ms | NA | 0.87 | 675 B | |
SnVec | BumpToNormal | .NET 6.0 | 3.858 ms | NA | 0.81 | 663 B | |
Vec128_Struct | BumpToNormal | .NET 6.0 | 2.886 ms | NA | 0.61 | 580 B | |
Vec128 | BumpToNormal | .NET 6.0 | 1.936 ms | NA | 0.41 | 503 B | |
Godot_Old | BumpToNormal | .NET 8.0 | 3.597 ms | NA | 0.76 | 482 B | |
Godot_New | BumpToNormal | .NET 8.0 | 3.569 ms | NA | 0.75 | 586 B | |
SnVec_Struct | BumpToNormal | .NET 8.0 | 2.907 ms | NA | 0.61 | 564 B | |
SnVec | BumpToNormal | .NET 8.0 | 2.495 ms | NA | 0.53 | 556 B | |
Vec128_Struct | BumpToNormal | .NET 8.0 | 2.181 ms | NA | 0.46 | 484 B | |
Vec128 | BumpToNormal | .NET 8.0 | 1.871 ms | NA | 0.39 | 470 B |
I'll contact you if these problems are not solved with next preview (or RC). Thanks.
Sounds good, thanks! You can notably get nightly builds here as well: https://github.com/dotnet/installer#installers-and-binaries
Also glad to see the improvements done in .NET 8 are paying off. Did quite a bit of refactoring and improvements, particularly to Quaternion
, Plane
, and Matrix4x4
. There's more still to land, but .NET 8 will be in a lot better shape than previous releases when it comes out in November.
^ .NET 8 is out now. Guess I will use .NET vectors for non-interfacing code for now, but some kind of parity would be nice for Godot Vectors.
Edit: Nevermind, seems like Godot vectors are already quite good according to AbeniMatteo tests.
Maybe some implicit cast from Numerics would be nice
@tannergooding If you're ever bored, you might take a look at System.Numerics.Vector3.Cross(). It's the only method that we're able to get noticeably faster performance from a custom function by converting to Vector128 and back. I believe the Numerics version is still only using scalar instructions.
If you're ever bored, you might take a look at System.Numerics.Vector3.Cross(). It's the only method that we're able to get noticeably faster performance from a custom function by converting to Vector128 and back. I believe the Numerics version is still only using scalar instructions.
This was done in https://github.com/dotnet/runtime/pull/103527, as was several other improvements including to matrix multiplication. It should be available in .NET 9 Preview 6.
Maybe some implicit cast from Numerics would be nice
Agree, is there a separate issue/discussion tracking that? I haven't found one yet, but there's a lot of different terms to search for. I guess that'd go in the proposals repo?
I was just doing some work to keep my game logic in an isolated C# project and was going to leverage the System.Numerics Vector3 to store my resulting data. It'd be nice if I could just directly assign it to the Node3D transforms and such within my game project layer.
I guess the question would be if implicit operators would be wanted, someone could run into issues with perf if they're not aware it's creating/converting behind the scenes, but an explicit conversion operator and/or extension method ToGodotVector()
would be nice:
public static class VectorExtensionMethods
{
public static Godot.Vector2 ToGodotVector(this System.Numerics.Vector2 v) => new(v.X, v.Y);
public static Godot.Vector3 ToGodotVector(this System.Numerics.Vector3 v) => new(v.X, v.Y, v.Z);
}
Godot version
4.0 beta 6
System information
Win 11, Ryzen 5 5600H, 32GB RAM
Issue description
Godot's integrated math library for .NET 6 is considerably slower than standard .NET System.Numerics.
Steps to reproduce
Do pretty much any Vector ops and compare it against System.Numerics. See included project for a small benchmark.
Minimal reproduction project
VectorBenchmark.zip