C#でのSIMDの利用方法

昨日 Visual Studio 2015 RC がリリースされました。64ビット環境では RyuJIT が搭載され、さらに速くなりますが、C# の実行速度はかなり速くなっており、もう、Visual C++ と大差がないようにすら感じます。

そして、さらなる高速化のため、SIMD (SSE2) が使えるようになりました。画像処理関係・マルチメディア処理関係で高速化が出来ます。

SIMD 関係、開発中は仕様が少しずつ変わっていました。もう RC であり、これで確定なのでしょう。ググって出てくる情報が開発中の仕様が大半のため、要注意です。

先に注意点

  1. マイクロソフトが実験的に書いていたサンプルは、現在のバージョンでは動かない物があります。
  2. 環境変数 COMPLUS_AltJit とか COMPLUS_FeatureSIMD 、レジストリいじったりとかは現在は不要です。
  3. Vector クラスが public ではなくなったため、ハードウェアアクセラレーションが有効になっているか取得する API が非公開になりました。

使い方

プロジェクトの設定はこれを変更します。

  • 「32ビットの優先」にチェックを外します。これをしないと RyuJIT が使われないのでしょう。
  • 「コードの最適化」にチェックを入れます。

「対象のフレームワーク」は .NET Framework 4.5 のままで大丈夫です。ただし、高速に実行させるには .NET Framework 4.6 が必要なはずです。Visual Studio は 2013 でも行けるのか試してないです。

NuGet パッケージマネージャーで System.Numerics.Vectors を追加します。


コードの書き方

コードの書き方はこんな感じです。

var v1 = new Vector4(1, 2, 3, 4);
var v2 = new Vector4(5, 6, 7, 8);
var v3 = v1 + v2;
Console.Out.WriteLine("v3 = {0}", v3);

ベンチマーク結果

足し算のベンチマークです。Vector4[1024] と float[4096] を比較しています。実行時間は for ループの処理も含んでいるので単純に4倍にはなりません。

環境 実行時間
Vector4[] (32ビット) 1,418
float[] (32ビット) 1,252
Vector4[] (64ビット) 407
float[] (64ビット) 874

「32ビットの優先」にチェックを付けるかどうかで大きく実行時間が変わります。上記、全て「コードの最適化」は有効になっています。

ドキュメント

API のリファレンスはここです。 https://msdn.microsoft.com/ja-jp/library/system.numerics(v=vs.111).aspx