Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A SIMD (egyetlen utasítás, több adat) hardveres támogatást nyújt egy művelet több adatrészen történő végrehajtásához, párhuzamosan egyetlen utasítás használatával. A .NET-ben SIMD-gyorsított típusok vannak a System.Numerics névtérben. A SIMD-műveletek hardverszinten párhuzamosak lehetnek. Ez növeli a vektoros számítások átviteli sebességét, amelyek gyakoriak a matematikai, tudományos és grafikus alkalmazásokban.
.NET SIMD által gyorsított típusok
A .NET SIMD által gyorsított típusok a következő típusokat tartalmazzák:
A Vector2, Vector3 és Vector4 típusok, amelyek 2, 3 és 4 Single értékkel rendelkező vektorokat ábrázolnak.
Két mátrixtípus, Matrix3x2amely egy 3x2-es mátrixot, és Matrix4x4egy 4x4-es értékmátrixot Single jelöl.
A Plane típus, amely egy síkot jelöl háromdimenziós térben értékek használatával Single .
A Quaternion típus egy vektort jelöl, amely a háromdimenziós fizikai forgások Single értékekkel történő kódolására szolgál.
A Vector<T> típus, amely egy adott numerikus típus vektorát jelöli, és a SIMD-támogatás előnyeit élvező operátorok széles halmazát biztosítja. A példányok száma Vector<T> egy alkalmazás teljes élettartama alatt rögzített, de az értéke Vector<T>.Count a kódot futtató gép processzorától függ.
Megjegyzés:
A típus Vector<T> nem szerepel a .NET-keretrendszerben. Ehhez a típushoz való hozzáféréshez telepítenie kell a System.Numerics.Vectors NuGet-csomagot.
A SIMD-gyorsított típusok úgy vannak implementálva, hogy nem SIMD-gyorsított hardverekkel vagy JIT-fordítókkal is használhatók legyenek. Annak megállapításához, hogy a SIMD-gyorsítás futásidőben elérhető-e, használja a Vector.IsHardwareAccelerated. Ha ez a tulajdonság visszatér true, legalább egyes API-k hardveresen gyorsított SIMD-műveleteket használnak. Ha visszaadja false, egyetlen API sem gyorsul fel a hardveren.
Hogyan kell használni a SIMD-t?
Egyéni SIMD-algoritmusok végrehajtása előtt ellenőrizheti, hogy a gazdagép támogatja-e a SIMD-t a következő használatával: Vector.IsHardwareAccelerated, amely egy Boolean-t ad vissza. Ez nem garantálja, hogy a SIMD-gyorsítás engedélyezve van egy adott típushoz, de azt jelzi, hogy bizonyos típusok támogatják.
Egyszerű vektorok
A .NET legprimitívebb SIMD-gyorsított típusai a Vector2Vector32, 3 és Vector4 4 Single értékű vektorokat jelölik. Az alábbi példa két vektor hozzáadását használja Vector2 .
var v1 = new Vector2(0.1f, 0.2f);
var v2 = new Vector2(1.1f, 2.2f);
var vResult = v1 + v2;
.NET-vektorokkal is kiszámíthatja a vektorok egyéb matematikai tulajdonságait, például Dot producta Transform , Clampés így tovább.
var v1 = new Vector2(0.1f, 0.2f);
var v2 = new Vector2(1.1f, 2.2f);
var vResult1 = Vector2.Dot(v1, v2);
var vResult2 = Vector2.Distance(v1, v2);
var vResult3 = Vector2.Clamp(v1, Vector2.Zero, Vector2.One);
Mátrix
Matrix3x2, amely egy 3x2 mátrixot jelöl, és Matrix4x4egy 4x4-et jelképező mátrixot. Mátrixhoz kapcsolódó számításokhoz használható. Az alábbi példa bemutatja egy mátrixnak a megfelelő transzponált mátrixával való szorzását SIMD használatával.
var m1 = new Matrix4x4(
1.1f, 1.2f, 1.3f, 1.4f,
2.1f, 2.2f, 3.3f, 4.4f,
3.1f, 3.2f, 3.3f, 3.4f,
4.1f, 4.2f, 4.3f, 4.4f);
var m2 = Matrix4x4.Transpose(m1);
var mResult = Matrix4x4.Multiply(m1, m2);
Vektor<T>
Ez Vector<T> lehetővé teszi a hosszabb vektorok használatát. A példányok száma Vector<T> rögzített, de az értéke Vector<T>.Count a kódot futtató gép processzorától függ.
Az alábbi példa bemutatja, hogyan számítható ki két tömb Vector<T>elemalapú összege.
double[] Sum(double[] left, double[] right)
{
if (left is null)
{
throw new ArgumentNullException(nameof(left));
}
if (right is null)
{
throw new ArgumentNullException(nameof(right));
}
if (left.Length != right.Length)
{
throw new ArgumentException($"{nameof(left)} and {nameof(right)} are not the same length");
}
int length = left.Length;
double[] result = new double[length];
// Get the number of elements that can't be processed in the vector
// NOTE: Vector<T>.Count is a JIT time constant and will get optimized accordingly
int remaining = length % Vector<double>.Count;
for (int i = 0; i < length - remaining; i += Vector<double>.Count)
{
var v1 = new Vector<double>(left, i);
var v2 = new Vector<double>(right, i);
(v1 + v2).CopyTo(result, i);
}
for (int i = length - remaining; i < length; i++)
{
result[i] = left[i] + right[i];
}
return result;
}
Megjegyzések
A SIMD nagyobb valószínűséggel távolít el egy szűk keresztmetszetet, és elérhetővé teszi a következőt, például a memória átviteli sebességét. A SIMD használatának teljesítménybeli előnye általában az adott forgatókönyvtől függően változik, és bizonyos esetekben még az egyszerűbb, nem SIMD-vel egyenértékű kódnál is rosszabb teljesítményt érhet el.