-
Notifications
You must be signed in to change notification settings - Fork 6k
Simd #13262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Simd #13262
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
8f5cdc5
mera added
FIVIL 64bcbd2
basic
FIVIL c79e9e1
vector and matrix
FIVIL 696d0e3
remarks
FIVIL 484b731
fixing headers problem
FIVIL 1a8e9df
Update simd.md
Thraka f2b7c84
Update docs/standard/simd.md
Thraka 657404f
Update docs/standard/simd.md
Thraka 3856a18
Apply suggestions from code review
Thraka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
--- | ||
title: SIMD in .NET | ||
description: This tutorial demonstrates how to use hardware SIMD operations in C# and .NET Core. | ||
author: FIVIL | ||
ms.author: tagoo | ||
ms.date: 03/31/2020 | ||
ms.technology: dotnet-standard | ||
--- | ||
|
||
# Overview | ||
|
||
SIMD (Single instruction, multiple data) provides hardware support for performing an operation on multiple pieces of data, in parallel, using a single instruction. In .NET, there's set of SIMD-accelerated types under the <xref:System.Numerics> namespace. SIMD operations can be parallelized at the hardware level. That increases the throughput of the vectorized computations, which are common in mathematical, scientific, and graphics apps. | ||
|
||
## .NET SIMD-accelerated types | ||
|
||
The .NET SIMD-accelerated types include the following types: | ||
|
||
- The <xref:System.Numerics.Vector2>, <xref:System.Numerics.Vector3>, and <xref:System.Numerics.Vector4> types, which represent vectors with 2, 3, and 4 <xref:System.Single> values. | ||
|
||
- Two matrix types, <xref:System.Numerics.Matrix3x2>, which represents a 3x2 matrix, and <xref:System.Numerics.Matrix4x4>, which represents a 4x4 matrix of <xref:System.Single> values. | ||
|
||
- The <xref:System.Numerics.Plane> type, which represents a plane in three-dimensional space using <xref:System.Single> values. | ||
|
||
- The <xref:System.Numerics.Quaternion> type, which represents a vector that is used to encode three-dimensional physical rotations using <xref:System.Single> values. | ||
|
||
- The <xref:System.Numerics.Vector%601> type, which represents a vector of a specified numeric type and provides a broad set of operators that benefit from SIMD support. The count of a <xref:System.Numerics.Vector%601> instance is fixed for the lifetime of an application, but its value <xref:System.Numerics.Vector%601.Count%2A?displayProperty=nameWithType> depends on the CPU of the machine running the code. | ||
|
||
> [!NOTE] | ||
> The <xref:System.Numerics.Vector%601> type is not included in the .NET Framework. You must install the [System.Numerics.Vectors](https://www.nuget.org/packages/System.Numerics.Vectors) NuGet package to get access to this type. | ||
|
||
The SIMD-accelerated types are implemented in such a way that they can be used with non-SIMD-accelerated hardware or JIT compilers. To take advantage of SIMD instructions, your 64-bit apps must be run by the runtime that uses the **RyuJIT** compiler. A **RyuJIT** compiler is included in .NET Core and in .NET Framework 4.6 and later. SIMD support is only provided when targeting 64-bit processors. | ||
|
||
## How to use SIMD? | ||
|
||
Before executing custom SIMD algorithms, it's possible to check if the host machine supports SIMD by using <xref:System.Numerics.Vector.IsHardwareAccelerated?displayProperty=nameWithType>, which returns a <xref:System.Boolean>. This doesn't guarantee that SIMD-acceleration is enabled for a specific type, but is an indicator that it's supported by some types. | ||
|
||
## Simple Vectors | ||
|
||
The most primitive SIMD-accelerated types in .NET are <xref:System.Numerics.Vector2>, <xref:System.Numerics.Vector3>, and <xref:System.Numerics.Vector4> types, which represent vectors with 2, 3, and 4 <xref:System.Single> values. The example below uses <xref:System.Numerics.Vector2> to add two vectors. | ||
|
||
```csharp | ||
var v1 = new Vector2(0.1f, 0.2f); | ||
var v2 = new Vector2(1.1f, 2.2f); | ||
var vResutl = v1 + v2; | ||
``` | ||
|
||
It's also possible to use .NET vectors to calculate other mathematical properties of vectors such as `Dot product`, `Transform`, `Clamp` and so on. | ||
|
||
```csharp | ||
var v1 = new Vector2(0.1f, 0.2f); | ||
var v2 = new Vector2(1.1f, 2.2f); | ||
var vResutl1 = Vector2.Dot(v1, v2); | ||
var vResutl2 = Vector2.Distance(v1, v2); | ||
var vResutl3 = Vector2.Clamp(v1, Vector2.Zero, Vector2.One); | ||
``` | ||
|
||
## Matrix | ||
|
||
<xref:System.Numerics.Matrix3x2>, which represents a 3x2 matrix, and <xref:System.Numerics.Matrix4x4>, which represents a 4x4 matrix. Can be used for matrix-related calculations. The example below demonstrates multiplication of a matrix to its correspondent transpose matrix using SIMD. | ||
|
||
```csharp | ||
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> | ||
|
||
The <xref:System.Numerics.Vector%601> gives the ability to use longer vectors. The count of a <xref:System.Numerics.Vector%601> instance is fixed, but its value <xref:System.Numerics.Vector%601.Count%2A?displayProperty=nameWithType> depends on the CPU of the machine running the code. | ||
|
||
The example below demonstrates adding long arrays elements using <xref:System.Numerics.Vector%601>. | ||
|
||
```csharp | ||
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; | ||
} | ||
``` | ||
|
||
## Remarks | ||
|
||
SIMD is more likely to remove one bottleneck and expose the next, for example memory throughput. 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. End with a note that users should benchmark and profile their code to identify hot spots and ensure that changes are meeting their performance goals/needs? Can we link to https://github.com/dotnet/BenchmarkDotNet? |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.