2017-11-23 13 views
1

グラフィックアプリケーションでは、SharpDX.Matrix3x2またはSystem.Numerics.Matrix3x2のいずれかを使用して行列を表すことができます。しかし、両方のマトリックスをパフォーマンステストで実行すると、SharpDXの行列は手間をかけてSystem.Numerics.Matrix3x2を時間の点で最大70%のマージンで打ち負かすことが分かりました。私のテストは非常に単純な繰り返し乗算でしたが、コードは次のとおりです。Matrix3x2パフォーマンス

var times1 = new List<float>(); 

for (var i = 0; i < 100; i++) 
{ 
    var sw = Stopwatch.StartNew(); 

    var mat = SharpDX.Matrix3x2.Identity; 

    for (var j = 0; j < 10000; j++) 
     mat *= SharpDX.Matrix3x2.Rotation(13); 

    sw.Stop(); 

    times1.Add(sw.ElapsedTicks); 
} 

var times2 = new List<float>(); 

for (var i = 0; i < 100; i++) 
{ 
    var sw = Stopwatch.StartNew(); 

    var mat = System.Numerics.Matrix3x2.Identity; 

    for (var j = 0; j < 10000; j++) 
     mat *= System.Numerics.Matrix3x2.CreateRotation(13); 

    sw.Stop(); 

    times2.Add(sw.ElapsedTicks); 
} 

TestContext.WriteLine($"SharpDX: {times1.Average()}\nSystem.Numerics: {times2.Average()}"); 

これらのテストは、Intel i5-6200Uプロセッサで実行しました。

ここで、私の質問は、SharpDXの行列がどのように高速化できるかです。 System.Numerics.Matrix3x2はSIMD命令を高速に実行することはできませんか?

SharpDX.Matrix3x2の実装はhereです。ご覧のとおり、これはプレーンなC#で書かれています。

+0

_ "System.Numerics.Matrix3x2がSIMD命令を使用してより高速に実行されるはずはありませんか?" - [はい、ただし.NET 4.6 x64のみ](https://docs.microsoft.com/en-us)/dotnet/standard/numericics#simd-enabled-vector-types)を参照してください。 – MickyD

+0

あなたのタイミングに欠陥がある可能性が高いです。正確な結果を得るには、[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet)のような標準的なベンチマークライブラリを使用してください。 – ja72

答えて

2

それは私のテストロジックが欠陥だったことが判明 - 私は回転行列乗算の作成をテストしていたことを意味し、回転行列内部ループを、作成していました。唯一のことは、ループを乗算した内を行い、私はSystem.Numerics.Matrix3x2からより良い性能を示す結果を受け取るようになったようにするため

var times1 = new List<float>(); 

for (var i = 0; i < 100; i++) 
{ 
    var sw = Stopwatch.StartNew(); 

    var mat = SharpDX.Matrix3x2.Identity; 

    var s = SharpDX.Matrix3x2.Scaling(13); 
    var r = SharpDX.Matrix3x2.Rotation(13); 
    var t = SharpDX.Matrix3x2.Translation(13, 13); 

    for (var j = 0; j < 10000; j++) 
    { 
     mat *= s; 
     mat *= r; 
     mat *= t; 
    } 

    sw.Stop(); 

    times1.Add(sw.ElapsedTicks); 
} 

var times2 = new List<float>(); 

for (var i = 0; i < 100; i++) 
{ 
    var sw = Stopwatch.StartNew(); 

    var mat = System.Numerics.Matrix3x2.Identity; 

    var s = System.Numerics.Matrix3x2.CreateScale(13); 
    var r = System.Numerics.Matrix3x2.CreateRotation(13); 
    var t = System.Numerics.Matrix3x2.CreateTranslation(13, 13); 

    for (var j = 0; j < 10000; j++) 
    { 
     mat *= s; 
     mat *= r; 
     mat *= t; 
    } 

    sw.Stop(); 

    times2.Add(sw.ElapsedTicks); 
} 

:私はこのように私のテストコードを修正しました。

別のポイント:SIMDの最適化が64ビットコードでのみ有効であるという事実には注意を払っていませんでした。 - およびVisual Studioの「優先32ビット」ボックスがグレー表示されるので、私

Platform Target | System.Numerics.Matrix3x2 | SharpDX.Matrix3x2 
--------------------------------------------------------------- 
AnyCPU   | 168ms      | 197ms 
x64    | 1.40ms     | 1.43ms 

私はAnyCPU下Environment.Is64BitProcessをチェックすると、それはfalseを返します。これらは、前とx64にプラットフォームを変更した後、私のテスト結果ですこの場合、AnyCPUはx86のエイリアスに過ぎないと考えられます。これは、x64でテストが2桁高速になる理由を説明しています。

0

テストでも考慮する必要がある点がいくつかあります。これらは単なるメモであり、現在の結果には影響しません。私もこのようなテストをやっています。

Sharpdxのいくつかの対応する関数は、オブジェクトではなく、参照で渡します。これは、参照したい関数と対応しています。あなたはあなたのテストでオペレータを使用しました(すべての良い、それは匹敵するテストです!)。状況によっては、演算子の使用が参照基準関数よりも遅い場合があります。