使用System.Numerics.Vectors旋转2D点

用户名

我正在寻找一个优化程序,该程序的很多计算都基于许多2D点的旋转。我到处搜索以查看是否有可能在C#中使用SIMD进行这些计算。

我在这里找到了一个c ++答案,似乎可以满足我的要求,但是我似乎无法使用System.Numerics.Vectors包将其转换为C#。

优化2D旋转

谁能为我指出正确的方向呢?

以下代码显示了不带SIMD的常规方法。其中Point是具有X和Y两倍的结构。

    public static Point[] RotatePoints(Point[] points, double cosAngle, double sinAngle)
    {
        var pointsLength = points.Length;
        var results = new Point[pointsLength];

        for (var i = 0; i < pointsLength; i++)
        {
            results[i].X = (points[i].X * cosAngle) - (points[i].Y * sinAngle);
            results[i].Y = (points[i].X * sinAngle) + (points[i].Y * cosAngle);
        }

        return results;
    }

编辑:我设法使用两个Vector <float>来实现一个实现,但是从基准测试来看,这似乎比以前的实现要慢很多。

    private static void RotatePoints(float[] x, float[] y, float cosAngle, float sinAngle)
    {
        var chunkSize = Vector<float>.Count;
        var resultX = new float[x.Length];
        var resultY = new float[x.Length];

        Vector<float> vectorChunk1;
        Vector<float> vectorChunk2;

        for (var i = 0; i < x.Length; i += chunkSize)
        {
            vectorChunk1 = new Vector<float>(x, i);
            vectorChunk2 = new Vector<float>(y, i);

            Vector.Subtract(Vector.Multiply(vectorChunk1, cosAngle), Vector.Multiply(vectorChunk2, sinAngle)).CopyTo(resultX, i);
            Vector.Add(Vector.Multiply(vectorChunk1, sinAngle), Vector.Multiply(vectorChunk2, cosAngle)).CopyTo(resultY, i);
        }
    }
哈罗德

在编辑中添加的代码是一个好的开始,但是它的代码源Vector.Multiply(Vector<float>, float)非常糟糕,因此应避免使用此功能。避免这种情况很容易,只需在循环外部广播并乘以一个向量即可。我还添加了一个更适当的循环绑定和“标量结尾”,以防向量大小不能很好地划分输入数组的大小。

private static void RotatePoints(float[] x, float[] y, float cosAngle, float sinAngle)
{
    var chunkSize = Vector<float>.Count;
    var resultX = new float[x.Length];
    var resultY = new float[x.Length];

    Vector<float> vectorChunk1;
    Vector<float> vectorChunk2;
    Vector<float> vcosAngle = new Vector<float>(cosAngle);
    Vector<float> vsinAngle = new Vector<float>(sinAngle);

    int i;
    for (i = 0; i + chunkSize - 1 < x.Length; i += chunkSize)
    {
        vectorChunk1 = new Vector<float>(x, i);
        vectorChunk2 = new Vector<float>(y, i);

        Vector.Subtract(Vector.Multiply(vectorChunk1, vcosAngle), Vector.Multiply(vectorChunk2, vsinAngle)).CopyTo(resultX, i);
        Vector.Add(Vector.Multiply(vectorChunk1, vsinAngle), Vector.Multiply(vectorChunk2, vcosAngle)).CopyTo(resultY, i);
    }
    for (; i < x.Length; i++)
    {
        resultX[i] = x[i] * cosAngle - y[i] * sinAngle;
        resultY[i] = x[i] * sinAngle + y[i] * cosAngle;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

缺少System.Numerics.Vectors.Vector <T>

使用AspNetCore.SignalR.Client nuget包时找不到SignalR-System.Numerics.Vectors v4.1.4

System.Numerics.Vectors'Vector <T>':基本上只是System.UInt128吗?

VS Code Omnisharp.MsBuild.Projectmanager无法加载程序集System.Numerics.Vectors 4.1.3.0

System.Numerics.Vector.GreaterThan and bool结果

System.Numerics.Vector.ConditionalSelect用来做什么?

Protobuff序列化System.Numerics.BigInteger

包装昂贵的System.Numerics.VectorX-为什么?

大数据集上的System.Numerics.Vector <T>

System.Numerics.Vector <int>仅部分初始化

C#哪里可以下载System.Numerics

在System.Numerics.Vector <T>中使用F#度量单位

尝试使用protobuf-net序列化System.Numerics.Quaternion

使用System.Numerics进行矩阵乘法的完全错误的值

我如何在MonoDevelop中的Mono C#中使用System.Numerics?

C#SIMD使用System.Numerics.Vector进行排序/中位数

如何使用MathNET.Numerics获得矢量幅度?

使用MathNet.Numerics进行矩阵求逆

为什么需要用这个简单的LINQ表达式引用System.Numerics?

如何在C#中获取System.Numerics.Vector的元素?

什么是Org.BouncyCastle.Math.BigInteger.ToByteArrayUnsigned的.NET System.Numerics.BigInteger等效项?

.NET Framework上System.Numerics.Vector <T>的初始化性能

C#中包含System.Numerics.Vector <double>的结构的指针

使用虚拟操纵杆旋转 2D Sprite

无法使用OpenGL正确旋转2D对象

使用split_on_numerics的word_delimiter删除所有令牌

Swift:以2D旋转点

System.Numerics.dll中的BigInteger类型和FSharp.Core.dll中的BigInteger类型之间有什么区别?

为什么System.Numerics命名空间中没有Matrix3x3?C#