Użyj SIMD — przyspieszone typy liczboweUse SIMD-accelerated numeric types

SIMD (pojedyncza instrukcja, wiele danych) zapewnia obsługę sprzętu na potrzeby wykonywania operacji na wielu danych, równolegle przy użyciu jednej instrukcji.SIMD (Single instruction, multiple data) provides hardware support for performing an operation on multiple pieces of data, in parallel, using a single instruction. W programie .NET istnieje zestaw SIMD-przyspieszone typy w System.Numerics przestrzeni nazw.In .NET, there's set of SIMD-accelerated types under the System.Numerics namespace. Operacje SIMD mogą być równoległe na poziomie sprzętu.SIMD operations can be parallelized at the hardware level. Zwiększa to przepływność obliczeń wektorowych, które są wspólne w aplikacjach matematycznych, naukowych i graficznych.That increases the throughput of the vectorized computations, which are common in mathematical, scientific, and graphics apps.

.NET SIMD — przyspieszone typy.NET SIMD-accelerated types

Typy przyspieszone dla programu .NET SIMD obejmują następujące typy:The .NET SIMD-accelerated types include the following types:

  • Vector2Typy, Vector3 i Vector4 , które reprezentują wektory z 2, 3 i 4 Single wartościami.The Vector2, Vector3, and Vector4 types, which represent vectors with 2, 3, and 4 Single values.

  • Dwa typy macierzy, Matrix3x2 , które reprezentują macierz 3 x 2, i Matrix4x4 , która reprezentuje macierz 4x4 Single wartości.Two matrix types, Matrix3x2, which represents a 3x2 matrix, and Matrix4x4, which represents a 4x4 matrix of Single values.

  • PlaneTyp, który reprezentuje płaszczyznę w trójwymiarowym miejscu przy użyciu Single wartości.The Plane type, which represents a plane in three-dimensional space using Single values.

  • QuaternionTyp, który reprezentuje wektor, który jest używany do kodowania trójwymiarowych obrotów fizycznych przy użyciu Single wartości.The Quaternion type, which represents a vector that is used to encode three-dimensional physical rotations using Single values.

  • Vector<T>Typ, który reprezentuje wektor określonego typu liczbowego i zawiera szeroki zestaw operatorów, które korzystają z obsługi SIMD.The Vector<T> type, which represents a vector of a specified numeric type and provides a broad set of operators that benefit from SIMD support. Liczba Vector<T> wystąpień jest ustalona przez okres istnienia aplikacji, ale jej wartość Vector<T>.Count zależy od procesora komputera, na którym uruchomiono kod.The count of a Vector<T> instance is fixed for the lifetime of an application, but its value Vector<T>.Count depends on the CPU of the machine running the code.

    Uwaga

    Vector<T>Typ nie jest uwzględniony w .NET Framework.The Vector<T> type is not included in the .NET Framework. Musisz zainstalować pakiet NuGet System. Numerics. Vectors , aby uzyskać dostęp do tego typu.You must install the System.Numerics.Vectors NuGet package to get access to this type.

Typy SIMD-przyspieszone są implementowane w taki sposób, że mogą być używane z akceleratorami sprzętu lub kompilatorów JIT nieSIMDymi.The SIMD-accelerated types are implemented in such a way that they can be used with non-SIMD-accelerated hardware or JIT compilers. Aby skorzystać z instrukcji SIMD, aplikacje 64-bitowe muszą być uruchamiane przez środowisko uruchomieniowe, które używa kompilatora RyuJIT .To take advantage of SIMD instructions, your 64-bit apps must be run by the runtime that uses the RyuJIT compiler. Kompilator RyuJIT jest dołączany do oprogramowania .NET Core i w .NET Framework 4,6 i nowszych.A RyuJIT compiler is included in .NET Core and in .NET Framework 4.6 and later. Obsługa SIMD jest zapewniana tylko w przypadku procesorów 64-bitowych.SIMD support is only provided when targeting 64-bit processors.

Jak używać SIMD?How to use SIMD?

Przed wykonaniem niestandardowych algorytmów SIMD można sprawdzić, czy maszyna hosta obsługuje SIMD przy użyciu Vector.IsHardwareAccelerated , która zwraca Boolean .Before executing custom SIMD algorithms, it's possible to check if the host machine supports SIMD by using Vector.IsHardwareAccelerated, which returns a Boolean. Nie gwarantuje to, że przyspieszenie SIMD jest włączone dla określonego typu, ale jest wskaźnikiem, który jest obsługiwany przez niektóre typy.This doesn't guarantee that SIMD-acceleration is enabled for a specific type, but is an indicator that it's supported by some types.

Proste wektorySimple Vectors

Najbardziej pierwotne typy SIMD-przyspieszone w programie .NET to Vector2 , Vector3 i Vector4 typy, które reprezentują wektory z 2, 3 i 4 Single wartościami.The most primitive SIMD-accelerated types in .NET are Vector2, Vector3, and Vector4 types, which represent vectors with 2, 3, and 4 Single values. Poniższy przykład używa Vector2 do dodawania dwóch wektorów.The example below uses Vector2 to add two vectors.

var v1 = new Vector2(0.1f, 0.2f);
var v2 = new Vector2(1.1f, 2.2f);
var vResult = v1 + v2;

Istnieje również możliwość użycia wektorów .NET do obliczenia innych właściwości matematycznych wektorów, takich jak Dot product , Transform , Clamp i tak dalej.It's also possible to use .NET vectors to calculate other mathematical properties of vectors such as Dot product, Transform, Clamp and so on.

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);

MacierzMatrix

Matrix3x2, która reprezentuje macierz 3 x 2, i Matrix4x4 reprezentuje macierz 4x4.Matrix3x2, which represents a 3x2 matrix, and Matrix4x4, which represents a 4x4 matrix. Może służyć do obliczeń dotyczących macierzy.Can be used for matrix-related calculations. W poniższym przykładzie pokazano mnożenie macierzy do macierzy transtransponowanej przy użyciu SIMD.The example below demonstrates multiplication of a matrix to its correspondent transpose matrix using SIMD.

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);

Niemożliwe<T>Vector<T>

Vector<T>Daje możliwość użycia dłuższych wektorów.The Vector<T> gives the ability to use longer vectors. Licznik Vector<T> wystąpienia został naprawiony, ale jego wartość Vector<T>.Count zależy od procesora komputera, na którym uruchomiono kod.The count of a Vector<T> instance is fixed, but its value Vector<T>.Count depends on the CPU of the machine running the code.

W poniższym przykładzie pokazano Dodawanie długich elementów tablic za pomocą Vector<T> .The example below demonstrates adding long arrays elements using Vector<T>.

double[] SimdVectorProd(double[] left, double[] right)
{
    var offset = Vector<double>.Count;
    double[] result = new double[left.Length];
    int i = 0;
    for (i = 0; i < left.Length; i += offset)
    {
        var v1 = new Vector<double>(left, i);
        var v2 = new Vector<double>(right, i);
        (v1 * v2).CopyTo(result, i);
    }

    //remaining items
    for (; i < left.Length; ++i)
    {
        result[i] = left[i] * right[i];
    }

    return result;
}

UwagiRemarks

SIMD może usunąć jedną wąskie gardła i uwidocznić kolejne, na przykład przepustowość pamięci.SIMD is more likely to remove one bottleneck and expose the next, for example memory throughput. Ogólnie rzecz biorąc, korzyści wynikające z używania SIMD różnią się w zależności od konkretnego scenariusza, a w niektórych przypadkach może to nawet być gorsza niż prostszy kod nieSIMD równoważny.In general the performance benefit of using SIMD varies depending on the specific scenario, and in some cases it can even perform worse than simpler non-SIMD equivalent code.