建立一個有效的SIMD雙精度的Vector3在.net當我問我的機器是否有可能基於矢量<double>
System.Numerics.Vector<double>.Count
答案是4
所以至少在我的機器中有足夠的SIMD位寄存器保存4個雙精度數字。
我試圖創建一個基於System.Numerics.Vector<double>
的Vector3 double,但我不認爲有可能創建一個與System.Numerics.Vector3
相同的形狀,其性能比沒有SIMD支持的基本C#代碼更好。
例如我的嘗試如下。我知道這是可怕的代碼。我只想探索我能用Vector<double>
做什麼。
System.Numerics.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]);
}
}
這是否工作? '+'和'*'似乎只有兩個項目返回'Vector'。所以試圖訪問'[2]'拋出一個'IndexOutOfRangeException'。 –
Corak
這取決於你的機器。它是硬件特定的。在我的機器上'Vector .Count''返回4.在你的機器上,它可能只返回2. –
bradgonesurfing
我已經讀了幾次這個問題,但它仍然不完全清楚你問的是什麼。爲什麼你不能使用'Vector3'?你不能用C#編寫自己的SIMD優化代碼。你有關於你發佈的代碼的具體問題?你只是想[審查](https://codereview.stackexchange.com/)? –