是否有可能在.Net中基于Vector <double>

时间:2017-07-10 10:08:25

标签: c# simd

当我问我的机器时

System.Numerics.Vector<double>.Count

答案是4,所以至少在我的机器上,SIMD寄存器中有足够的位来保存4个双精度数。

我尝试根据System.Numerics.Vector<double>创建一个Vector3双精灵,但我不认为可以创建一个与System.Numerics.Vector3具有相同形状的曲面,而不仅仅是System.Numerics.Vector<double>没有SIMD支持的基本C#代码。

例如,我的尝试如下。我知道这是可怕的代码。我只想探索一下Vector<double>可以做些什么。

BottomTabBar没有构造函数可以使用 N 参数。我理解为什么。这是因为在编译时你不知道有多少双打可以放进Vector<double>,所以图书馆作家可以保护我不会在脚下射击。

但是,如果我愿意冒险做一些足部射击,我可以改进下面的代码吗?

using System.Numerics;

public struct Vector3Double
{

    public readonly double X;
    public readonly double Y;
    public readonly double Z;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Vector3Double(double x, double y, double z) : this()
    {
        X = x;
        Y = y;
        Z = z;
    }

    // Factory for SIMD Vector<double> but it is slow because
    // I need to create an array on the heap to initialize
    static Vector<double> vd(double x, double y, double z) 
        => new Vector<double>(new []{x,y,z,0});


    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static double Dot(Vector3Double a, Vector3Double b)
    {
        var s = vd( a.X, a.Y, a.Z ) * vd( b.X, b.Y, b.Z );
        return s[0] + s[1] + s[2];
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Vector3Double Add(Vector3Double a, Vector3Double b)
    {
        var s = vd( a.X, a.Y, a.Z ) + vd( b.X, b.Y, b.Z );
        return new Vector3Double( s[0], s[1], s[2] );
    }
}

1 个答案:

答案 0 :(得分:1)

如果你认为你的Vector3d的大小= 16,有一种方法可以做到,就像你有第四个坐标一样。然后你可以使用Unsafe.Read&lt; Vector&lt; double&gt;&gt;(和&amp; v3d),它会对Vector3d进行不安全的转换为&lt; double&gt;。请注意,仅当Vector&lt; double&gt; .Count为4时,此功能才有效! 在Vector&lt; double&gt;上进行simd操作后您可以再次使用Unsafe.Read&lt; Vector3d&gt;(&amp; result)将结果强制转换回Vector3d。