当我问我的机器时
System.Numerics.Vector<double>.Count
答案是4
,所以至少在我的机器上,SIMD寄存器中有足够的位来保存4个双精度数。
我尝试根据System.Numerics.Vector<double>
创建一个Vector3双精灵,但我不认为可以创建一个与System.Numerics.Vector3
具有相同形状的曲面,而不仅仅是System.Numerics.Vector<double>
没有SIMD支持的基本C#代码。
例如,我的尝试如下。我知道这是可怕的代码。我只想探索一下Vector<double>
可以做些什么。
没有构造函数可以使用 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] );
}
}
答案 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。