Question

Perhaps I'm doing something wrong, but i get that SIMD is slower, than scallar version.

I just want to increment values of array. I'm using Microsoft SIMD (NuGet package Microsoft.Bcl.Simd Prerelease). It's beta, but it should work fine with int and float, but it doesn't.

My bench

using System;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace ConsoleApplication58
{
    class Program
    {
        static void Main()
        {
            var r = new Random();
            var sw = Stopwatch.StartNew();
            int[] values = Enumerable.Range(0, 1000000).ToArray();
            sw.Stop();
            Console.WriteLine("TEST GENERATED IN {0}", sw.Elapsed);
            int trash = 0;
            Stopwatch sw1 = new Stopwatch(), sw2 = new Stopwatch();
            for (int i = 0; i < 100; i++)
            {
                sw1.Start();
                var result = SimdIncrement(values, 10);
                sw1.Stop();
                sw2.Start();
                var result2 = SimpleIncrement(values, 10);
                sw2.Stop();

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();

                unchecked
                {
                    trash ^= result[r.Next(values.Length)];
                    trash ^= result2[r.Next(values.Length)];
                }
            }
            Console.WriteLine("SIMD = {0}", sw1.Elapsed);
            Console.WriteLine("Brute = {0}", sw2.Elapsed);

            Console.WriteLine("Trash value = {0}", trash);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static int[] SimpleIncrement(int[] values,int inc)
        {
            int[] result = new int[values.Length];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = values[i] + inc;
            }
            return result;
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static int[] SimdIncrement(int[] values,int inc)
        {
            int[] result = new int[values.Length];
            for (int i = 0; i < values.Length; i += 4)
            {
                var vector = new Vector<int>(values, i);
                var increment = new Vector<int>(inc);
                vector += increment;
                vector.CopyTo(result, i);
            }
            return result;
        }
    }
}

Results:

TEST GENERATED IN 00:00:00.0171804
SIMD = 00:00:02.1456817
Brute = 00:00:00.1576084
Trash value = 548547
Press any key . . .
Était-ce utile?

La solution

I hate to be even more snippy, but where is any SIMD here? The Microsoft SIMD package will not do SIMD instructions.... it is normal bytecode. To make it use SIMD, you must install RyuJit and tell it.

This is compatibility mode - the MS SIMD classes contain bytecode for normal operations. The new runtime will know how to handle them without touching the byte code, but you must install it at the moment (prerelease).

http://blogs.msdn.com/b/dotnet/archive/2013/09/30/ryujit-the-next-generation-jit-compiler.aspx

Let me quote from the package:

The types in this package are implemented in IL which allows them to be used on non-SIMD enabled JIT compilers and hardware. However, in order to actually use SIMD instructions, you'll need to run on a JIT compiler that knows about these types in order to emit SIMD instructions. The current .NET 4.5.1 runtime doesn't. The .NET code generation team has published a CTP of the the new JIT, codenamed "RyuJIT". The CTP adds SIMD support when compiling for x64.

Autres conseils

Your SIMD version should be changed to a real vector based addition method:

[MethodImpl(MethodImplOptions.NoInlining)]
private static int[] simdIncrement(int[] values, int inc)
{    
    var vector = new Vector<int>(values);
    var vectorAddResults = vector + new Vector<int>(inc);

    var result = new int[values.Length];
    vectorAddResults.CopyTo(result);
    return result;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top