はじめてのSIMD
MonoがSIMDに対応したので実験君。
※SIMDについては→IT マネージャーおよび担当者向けリソース
私にSIMDは門外漢過ぎるのでhttp://cell.fixstars.com/pukiwiki/index.php?simd_0_lesson1から例題を拝借しました。(^^;
using Mono; using Mono.Simd; using System; using System.Diagnostics; public class Program { public static void Main(string[] args) { const int LOOP=10000000; Vector4i vi = new Vector4i(1, 2, 3, 4); Vector4i vo = new Vector4i(0, 0, 0, 0); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < LOOP; ++i) vo += vi; Console.WriteLine ("{0},{1},{2},{3}", vo.X, vo.Y, vo.Z, vo.W); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } } // vim:set ts=4 sts=4 sw=4:
サンプルは単純にVector4を加算するだけのものです。これをsimd.csとか名前をつけて保存し、コンパイル。
$ gmcs /r:Mono.Simd.dll simd.cs
では、実行してみます。まずは、SIMDをオフで。
$ mono -O=-simd simd.exe 10000000,20000000,30000000,40000000 1387
実行結果は1387msでした。
次に、SIMDをオンにします。(デフォルトがオン)
$ mono simd.exe 10000000,20000000,30000000,40000000 114
114ms。10倍以上高速化されています*1。実際のマシン語を見てみると、
80: 0f 10 45 a8 movups -0x58(%ebp),%xmm0 84: 0f 10 4d c8 movups -0x38(%ebp),%xmm1 88: 66 0f fe c1 paddd %xmm1,%xmm0 8c: 0f 11 45 a8 movups %xmm0,-0x58(%ebp) 90: 46 inc %esi
SSE命令であるmovupsが見つかりますね。
PDC2008のMonoセッションをでは、Monoがゲームに使われる例が紹介されていましたが、ゲームの動作環境としてのニーズが高まればこのような機能が望まれていくのでしょうね。本家MS.NETでも同様の機能を組み込んでくれるとうれしいのですが・・・