コンテンツにスキップ
メインメニュー
メインメニュー
サイドバーに移動
非表示
案内
メインページ
最近の更新
未作成ページ
おまかせ表示
ヘルプ
MonoBook
検索
検索
ログイン
個人用ツール
ログイン
ログアウトした編集者のページ
もっと詳しく
投稿記録
トーク
「
System.Numerics.Vector<T>
」を編集中
ページ
議論
日本語
閲覧
編集
ソースを編集
履歴表示
ツール
ツール
サイドバーに移動
非表示
操作
閲覧
編集
ソースを編集
履歴表示
全般
リンク元
関連ページの更新状況
特別ページ
ページ情報
2020年5月27日 (水) 04:57時点における
Administrator
(
トーク
|
投稿記録
)
による版
(
→ベンチマーク
)
(
差分
)
← 古い版
|
最新版
(
差分
) |
新しい版 →
(
差分
)
警告: このページの古い版を編集しています。
公開すると、この版以降になされた変更がすべて失われます。
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。
スパム攻撃防止用のチェックです。 けっして、ここには、値の入力は
しない
でください!
System.Numerics.Vector<T>はSIMDレジスタを表す不変の構造体である。 こいつを使うと[[.NET]]の[[ランタイム]]が上手いこと解釈して[[SIMD]]で加速される。 なお「SIMD演算器がある場合に」と注釈があり、加速されないこともあるようなことが書いてあるが、 [[Android]]最初期の[[T-01C]]などに搭載された[[Snapdragon S1]]([[QSD8250]])ですら[[SIMD]]([[NEON]])を搭載しているわけで、 いまどき[[SIMD]]が搭載されていない[[CPU]]は存在するのか謎である。 というか、それより下のクラスの組み込み系[[CPU]]で[[.NET]]がまともに動くのか謎である。 Vector<T>はVector<T>.Countの大きさの配列のようなものである。 Vector<int>は「intが8個の配列」のような感じだ。 あとは普通に[[四則演算]]などをすると内部で[[ベクトル演算]]が行われる。 *https://docs.microsoft.com/ja-jp/dotnet/api/system.numerics.vector-1?view=netcore-3.1 <source lang="csharp"> var v1 = new Vector<int>(1,2,3,4,5,6,7,8); var v2 = new Vector<int>(1,2,3,4,5,6,7,8); // ベクトル演算が行われる var v3 = v1 + v2; // v3 = <2, 4, 6, 8, 10, 12, 14, 16> </source>四則演算だけでなくVectorクラスにはMinやMaxやDotなども用意されている。 *https://docs.microsoft.com/ja-jp/dotnet/api/system.numerics.vector?view=netcore-3.1 ==Vector<T>.Countプロパティ== 1つのVector<T>構造体に格納可能な変数の数を得られる。 CPUのSIMDレジスタの幅だな。<source lang="csharp"> // SIMDレジスタにintを格納できる数 var regs = Vector<int>.Count; // intのビット数 var bits = sizeof(int) * 8; // SIMDレジスタのビット数 var simd = bits * count; Console.WriteLine($"{simd}bit = {bits}bit * {regs}unit"); // 256bit = 32bit * 8unit </source> ==Vector<T>のコンストラクタ== 引数1つ指定するとVector<T>.Countの数だけ埋め尽くされる。 var v = new Vector<int>(1); // v = <1,1,1,1,1,1,1,1>; 引数に配列を指定するとVector<T>.Countの数だけ埋め尽くされる。 var v = new Vector<int>(new[]{1,2,3,4,5,6,7,8}); // v = <1,2,3,4,5,6,7,8>; 配列の要素数がVector<T>.Countより多いと、多い分は無視される。以下だと1から8までが格納される。 var v = new Vector<int>(new[]{1,2,3,4,5,6,7,8,9,10}); // v = <1,2,3,4,5,6,7,8>; index引数を指定すると配列のその位置から格納される。以下だと3から10までが格納される。巨大な配列を逐次処理するのに便利だな。 var v = new Vector<int>(new[]{1,2,3,4,5,6,7,8,9,10}, index:2); v = <3,4,5,6,7,8,9,10>; 配列の要素数がVector<T>.Countより少ないと、System.IndexOutOfRangeExceptionを吐く。 巨大な配列をインデックス指定でぶん回す場合は配列の要素数がVector<T>.Countで割り切れるようにパディングするといいな。 var v = new Vector<int>(new[]{1,2,3,4,5,6,7}); // System.IndexOutOfRangeException == 使ってみる == 配列が小さい(64未満くらい)と逆に遅くなる模様。 <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> 加速されすぎ。
編集内容の要約:
MonoBookへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MonoBook:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の確認用の質問に回答してください (
詳細
):
1たす1は?(全角で入力してください)
キャンセル
編集の仕方
(新しいウィンドウで開きます)
本文の横幅制限を有効化/無効化