「System.Numerics.Vector<T>」の版間の差分

ページの作成:「System.Numerics.Vector<T>はSIMDレジスタを表す不変の構造体である。 こいつを使うと.NETランタイムが上手いこと解釈してSI…」
 
 
(同じ利用者による、間の6版が非表示)
11行目: 11行目:
*https://docs.microsoft.com/ja-jp/dotnet/api/system.numerics.vector-1?view=netcore-3.1
*https://docs.microsoft.com/ja-jp/dotnet/api/system.numerics.vector-1?view=netcore-3.1
<source lang="csharp">
<source lang="csharp">
var v1 = Vector<int>(1,2,3,4,5,6,7,8);
var v1 = new Vector<int>(1,2,3,4,5,6,7,8);
var v2 = Vector<int>(1,2,3,4,5,6,7,8);
var v2 = new Vector<int>(1,2,3,4,5,6,7,8);


// ベクトル演算が行われる
// ベクトル演算が行われる
52行目: 52行目:
  var v = new Vector<int>(new[]{1,2,3,4,5,6,7});
  var v = new Vector<int>(new[]{1,2,3,4,5,6,7});
  // System.IndexOutOfRangeException
  // System.IndexOutOfRangeException
== 使ってみる ==
基本は以下の繰り返し。
* 配列の一部分をVector<T>に格納する
* ベクトル演算を実行する
* 演算結果のVector<T>を配列に書き戻す
<source lang="csharp">
// 配列を用意する
var array = Enumerable.Range(0, 1024).ToArray();
var arraySize = array.Length;
// SIMDサイズ
var simdSize = Vector<int>.Count;
// インクリメント用
var one = Vector<int>.One;
// 実行
for (int index = 0; index < arraySize; index += simdSize)
{
    // 配列をSIMDレジスタに格納
    var vector = new Vector<int>(array, index);
    // ベクトル演算Add
    vector += one;
    // SIMDレジスタを配列に書き戻す
    vector.CopyTo(array, index);
}
</source>
== ベンチマーク ==
[[BenchmarkDotNet]]で単純な[[インクリメント]]を比較してみた。
備考:比較対象のScalarOpはこんな感じ。
<source lang="csharp">
for (int index = 0; index < arraySize; index ++)
{
    array[index] += 1;
}
</source>
結果。
<source>
BenchmarkDotNet=v0.12.1, OS=macOS Catalina 10.15.4 (19E287) [Darwin 19.4.0]
Intel Core i7-8700B CPU 3.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.1.300
  [Host]    : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
  Job-AGKFKU : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
InvocationCount=1  UnrollFactor=1 
|  Method | ArraySize |      Mean |    Error |  StdDev |    Median |
|--------- |---------- |----------:|----------:|---------:|----------:|
| ScalarOp |      512 | 320.43 ns | 10.136 ns | 29.89 ns | 315.00 ns |
| VectorOp |      512 | 159.76 ns |  9.236 ns | 27.09 ns | 166.50 ns |
| ScalarOp |      1024 | 574.93 ns | 13.965 ns | 13.06 ns | 575.00 ns |
| VectorOp |      1024 | 169.69 ns |  9.599 ns | 28.00 ns | 170.50 ns |
</source>
加速されすぎ。