Обучение
Модуль
Выбор правильного типа данных в коде на C# - Training
Выберите правильный тип данных для кода из нескольких основных типов, используемых в C#.
Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
SIMD (одна инструкция, несколько данных) обеспечивает поддержку оборудования для выполнения операции с несколькими частями данных параллельно с помощью одной инструкции. В .NET в пространстве имен есть набор типов System.Numerics с ускорением SIMD. Операции SIMD можно параллелизировать на уровне оборудования. Эта возможность повышает производительность векторизированных вычислений, которые широко применяются в математических, научных и графических приложениях.
Типы ускорения .NET SIMD включают следующие типы:
Типы Vector2, Vector3 и Vector4, которые представляют векторы с 2, 3 и 4 значениями Single.
Два типа матрицы, Matrix3x2представляющий матрицу 3x2 и Matrix4x4матрицу, представляющую матрицу 4x4 значений Single .
Тип Plane , представляющий плоскость в трехмерном пространстве с помощью Single значений.
Тип Quaternion , представляющий вектор, используемый для кодирования трехмерных физических поворотов с помощью Single значений.
Тип Vector<T>, который представляет вектор указанного числового типа и реализует широкий набор операторов, оптимизированных для поддержки SIMD. Число экземпляров Vector<T> исправлено в течение времени существования приложения, но его значение Vector<T>.Count зависит от ЦП компьютера, выполняющего код.
Примечание
Тип Vector<T> не включен в платформа .NET Framework. Чтобы получить доступ к этому типу, необходимо установить пакет NuGet System.Numerics.Vectors.
Типы с ускорением SIMD реализуются таким образом, что их можно использовать с аппаратным оборудованием без SIMD или компиляторами JIT. Чтобы воспользоваться инструкциями SIMD, 64-разрядные приложения должны запускаться средой выполнения, используюющей компилятор RyuJIT . Компилятор RyuJIT входит в .NET Core и в платформа .NET Framework 4.6 и более поздних версий. Поддержка SIMD предоставляется только при выборе 64-разрядных процессоров.
Перед выполнением пользовательских алгоритмов SIMD можно проверка, если хост-компьютер поддерживает SIMD с помощью Vector.IsHardwareAccelerated, который возвращает Booleanзначение. Это не гарантирует, что для определенного типа включено ускорение SIMD, но является индикатором, поддерживаемым некоторыми типами.
Наиболее примитивные типы с ускорением SIMD в .NET: Vector2Vector3и Vector4 типы, представляющие векторы с 2, 3 и 4 Single значениями. В приведенном ниже примере используется Vector2 для добавления двух векторов.
var v1 = new Vector2(0.1f, 0.2f);
var v2 = new Vector2(1.1f, 2.2f);
var vResult = v1 + v2;
Кроме того, можно использовать векторы .NET для вычисления других математических свойств векторов, таких как Dot product
, Transform
Clamp
и т. д.
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);
Matrix3x2, представляющий матрицу 3x2 и Matrix4x4, представляющую матрицу 4x4. Можно использовать для вычислений, связанных с матрицами. В приведенном ниже примере показано умножение матрицы на ее корреспондентную транспонированную матрицу с помощью 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);
Это Vector<T> дает возможность использовать более длинные векторы. Число экземпляров Vector<T> исправлено, но его значение Vector<T>.Count зависит от ЦП компьютера, на котором выполняется код.
В следующем примере показано, как вычислить мудрую сумму элементов двух массивов с помощью Vector<T>.
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;
}
SIMD более вероятно, чтобы удалить одно узкие места и предоставить следующую, например пропускную способность памяти. В целом преимущество производительности использования SIMD зависит от конкретного сценария, и в некоторых случаях это может даже хуже, чем простой эквивалентный код, отличный от SIMD.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Обучение
Модуль
Выбор правильного типа данных в коде на C# - Training
Выберите правильный тип данных для кода из нескольких основных типов, используемых в C#.