Please think about implementing this operator:
Vector3.CopyTo(Span
Since the span can be a stackallocated Array the performance gain should be huge! Also Vertical Operators are missing from Vector
Thanks for the suggestion @dangi12012. Can you please refer to the API review process guidelines here.
The issue description should contain a speclet that represents a sketch of the new APIs, including samples on how the APIs are being used. The goal isn't to get a complete API list, but a good handle on how the new APIs would roughly look like and in what scenarios they are being used. Here is a good example.
For reference. here are the existing CopyTo methods on Vector3:
C#
public struct Vector3 : IEquatable<Vector3>, IFormattable
{
public void CopyTo(float[] array);
public void CopyTo(float[] array, int index);
}
cc @eerhardt
If you add the following code to Vector2,3,4 and Vector
public Vector3(Span<float> Elements)
{
ElementPtr = Elements.ToArray();
}
public static implicit operator Vector3((float x, float y, float z) elements)
{
return new Vector3(elements.x, elements.y, elements.z);
}
public void Deconstruct(out float x, out float y, out float z)
{
x = X;
y = Y;
z = Z;
}
static void Showcase()
{
Vector3 v = (3, 2, 1); //Asume we have vector or vector<T> SIMD
Span<float> span = stackalloc float[3]; //Now we want to implement our own operator not implemented in SIMD
v.CopyTo(span); //getting single element is very slow for vector<T>. Creating an array is also VERY slow compared to c++ SIMD. Solution: SPAN<T>
//Take modulus
span[0] = span[0] % 2.0f;
span[1] = span[1] % 2.0f;
span[2] = span[2] % 2.0f;
Vector3 result = new Vector3(span); //Fast modulus. If you make Vectors special types like span no copy is needed here. (Span as backing field)
var (x, y, z) = v; //This is support for Deconstruct
}
This is faster than what we currently have for not unsupported Vectormath. (Vector
An update to support CopyTo(span) would be needed for perfromance critical code.
The speed can even be improved to 0 copy, with the new ref return in C# 7:
public ref float X() => ref ElementPtr.Span[0];
I would widen this request to initialize a Vector
In some scenarios where you really need performance (e.g. bilinear interpolation) you need to fill a lot of interpolation partners. Currently, first you have to load your interpolation partners in a newly allocated arrays, which you only need to create your Vector
For this situations it makes much more sense to stackalloc the memory for your interpolation partners that you refill with new data in a loop. If the stackalloc'ed memory can be Span
Vector<T> already has CopyTo(System.Span<T>). This was added in https://github.com/dotnet/coreclr/pull/23333.
Vector2/3/4 do not have it and I would be fine with adding them, but would like the existing proposal (or a new one given it hasn't been updated by the OP in over a year), following the good example @ahsonkhan listed https://github.com/dotnet/corefx/issues/28433#issuecomment-375849157 put up before I mark this as api-ready-for-review.
Tuple deconstruction should be in its own issue and follow the good example as well @dangi12012.
@tannergooding: You are right, CopyTo is there, but correct me if I'm wrong there's nothing for the constructor, right? So I cannot do something like
Span<float> x = stackalloc float[]{10,20,30,40};
Vector<float> v = new Vector<float>(x);
Currently only this is possible:
float[] x = new float[]{10,20,30,40};
Vector<float> v = new Vector<float>(x);
which could cause pressure on the GC when doing this in a loop in x/x direction over many data points.
The Vector(Span<T>) constructor has existed for over a year now and was added in https://github.com/dotnet/coreclr/pull/16733.
The Vector(ReadOnlySpan<T>) constructor was added in the https://github.com/dotnet/coreclr/pull/23333 PR I linked above.
@tannergooding: Thanks a lot for pointing this out. I did it today, but I looked it up again. According to the docs it only works for .NET Standard 2.1 Preview, whereas I am on .NET Standard 2.0.
But you can do
float* x = stackalloc float[] { 10, 20, 30, 40 };
Vector<float> v = Unsafe.ReadUnaligned<Vector<float>>(x);
@benaadams 馃憤 This might help. I'll give it a try.
@dangi12012, could you please update the original post to follow the "good example" listed under step 1 of our API Review Process? You don't need to provide all sections, but ideally you would provide the rationale and proposed API surface sections as those help the API review process.
Most helpful comment
If you add the following code to Vector2,3,4 and Vector:
This is faster than what we currently have for not unsupported Vectormath. (Vector is very lacking with horizontal operations and intrinsics)
An update to support CopyTo(span) would be needed for perfromance critical code.
The speed can even be improved to 0 copy, with the new ref return in C# 7:
public ref float X() => ref ElementPtr.Span[0];