15

I was reading a question about c# code optimization and one solution was to use c++ with SSE. Is it possible to do SSE directly from a c# program?

Rex Logan
  • 26,248
  • 10
  • 35
  • 48

10 Answers10

17

The upcoming Mono 2.2 release will have SIMD support. Miguel de Icaza blogged about the upcoming feature here, and the API is here.

Although there will be a library that will support development under Microsoft's .NET Windows runtime, it will not have the performance benefits that you are looking for unless you run the code under the Mono runtime. Which might be doable depending on your circumstances.

Update: Mono 2.2 is released

Amir
  • 4,131
  • 26
  • 36
  • Ah, this would be so nice in .NET. Kudos to Mono for even making a software implementation for .NET, but shame on MS. – Camilo Martin Dec 23 '11 at 05:56
  • What if somehow I link c++ .dll for my c# project? Can I use intrinsics inside? – huseyin tugrul buyukisik Jul 19 '13 at 16:46
  • Update: The official MS .NET runtime is getting SIMD support as well (it's currently in CTP phase). http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx – BrainSlugs83 Sep 01 '14 at 23:08
  • 2
    FYI, the latest version of the next Runtime is CTP4 (if I'm not mistaken), you can download it here: http://blogs.msdn.com/b/clrcodegeneration/archive/2014/05/12/ryujit-ctp4-now-with-more-simd-types-and-better-os-support.aspx -- and the code is backwards compatible with the non-CTP runtime, so it will still work, it just won't take advantage of SIMD instructions. – BrainSlugs83 Sep 01 '14 at 23:18
7

Can C# explicitly make an SSE call?

No. C# cannot produce inline IL much less inline x86/amd64 assembly.

The CLR, and more specifically the JIT, will use SSE if it's available removing the need to force it in most circumstances. I say most because I'm not an SSE expert and I'm sure that there are cases where it could be beneficial and the JIT does not make the optimization.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    Can you give a reference and/or example of where the JIT will employ SSE? Is there a way to write code in an SSE-friendly manner? – Konrad Rudolph Feb 04 '09 at 15:48
  • 7
    @Konrad, check out David Notario's blog. He has some details about where the CLR uses SSE2. http://blogs.msdn.com/davidnotario/archive/2005/08/15/451845.aspx – JaredPar Feb 05 '09 at 14:31
  • 3
    I know this is an old response, but it is actually possible to execute arbitrary assembly in C#. You don't need unsafe, and you don't need post-compilers. You do need code permission to call Win32 VirtualAlloc. See http://stackoverflow.com/a/7964376/344638 – antiduh Jul 08 '14 at 21:00
  • This answer is now obsolete, I think; C# does have SSE/AVX or at least generic-SIMD. Not sure if it really exposes SSE shuffles and stuff like `phminposuw` or `psadbw` horizontal operations or only generic vertical ops like add on vectors of primitive types. – Peter Cordes Oct 11 '19 at 01:44
5

SIMD for .NET will be available in the near future. RyuJIT (the next-generation JIT compiler for .NET) required for this feature ATM.

You should use Microsoft.Numerics.Vectors.Vector<T> class from Microsoft.Bcl.Simd package to take advantage of this feature. Sample code here.

KindDragon
  • 6,558
  • 4
  • 47
  • 75
4

Based on this forum posting, the MS JIT compiler automatically uses SSE if SSE is available on the target machine.

Paul Whitehurst
  • 579
  • 2
  • 9
  • 10
    Sort of. It checks the rev of SSE to know if it has access to some nice general purpose instructions like LZCNT, POPCNT, and a few instructions that will use the extended registers to move larger block of memory. It won't auto-parallelize anything. – Joe Jan 22 '09 at 00:37
2

Recently Microsoft has released a beta SIMD vector library (Microsoft.Bcl.Simd) for C# which requires installation of the RyuJIT CTP and works only Windows 8.

You can also just used a native SSE library and invoke it from C#. For example the Yeppp library, see this StackOverflow answer.

Community
  • 1
  • 1
cdiggins
  • 17,602
  • 7
  • 105
  • 102
2

It is finally possible. Here the post http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx

Andreas
  • 3,843
  • 3
  • 40
  • 53
2

If you have a 'chunk' of work you want to do, the best bet is to write it in C++ using the MMX/SSE intrinsics and then make a very simple /clr managed C++ class that wraps your functionality and exposes it out as a .net class. Then your code can just use that assembly as if it were a normal class.

For more about the VC intrinsics you can look at this little ditty I wrote many years ago.

http://msdn.microsoft.com/en-us/library/0aws1s9k.aspx

Oh - I'm assuming you are actually wanting to use the parallel functions to speed something up. As others have pointed out - if you just want to move data in larger chunks and the like, the JIT already knows how to use SSE for those basics.

Joe
  • 2,946
  • 18
  • 17
2

Filip is correct. I have another, older post showing a similar, but more detailed example. I have actually run this code, and modified it myself to prove to myself that it works. I am contemplating using this technique in a project I am working and is why I am out looking to see what may be new since this is a bit old. As the author implies, you can write any function you wish in C++, compile it, then copy the bytes into your C#.

http://blogs.msdn.com/b/devinj/archive/2005/07/12/438323.aspx

I would add that Joe's CLI C++ class is a good idea as well, however, I don't think the sse compiler flag and the /clr flag are compatible on the same project. I just verified that: have to write your high perf code in a separate project to use the SSE (/arch:sse or /arch:sse2) compiler flag as /clr is incomatible. To do anything much more complex than do simple arithmetic on a few inputs, I think this is the best approach.

seljo
  • 21
  • 3
1

Modern C# Supports SIMD/SSE instructions well and makes them fairly simple to use. Not all instructions are yet supported.

Here is an example of an SSE .Sum() of an array of uint[]:

    using System.Numerics;

    private static ulong SumSseInner(this uint[] arrayToSum, int l, int r)
    {
        var sumVectorLower = new Vector<ulong>();
        var sumVectorUpper = new Vector<ulong>();
        var longLower      = new Vector<ulong>();
        var longUpper      = new Vector<ulong>();
        int sseIndexEnd = l + ((r - l + 1) / Vector<uint>.Count) * Vector<uint>.Count;
        int i;
        for (i = l; i < sseIndexEnd; i += Vector<int>.Count)
        {
            var inVector = new Vector<uint>(arrayToSum, i);
            Vector.Widen(inVector, out longLower, out longUpper);
            sumVectorLower += longLower;
            sumVectorUpper += longUpper;
        }
        ulong overallSum = 0;
        for (; i <= r; i++)
            overallSum += arrayToSum[i];
        sumVectorLower += sumVectorUpper;
        for (i = 0; i < Vector<long>.Count; i++)
            overallSum += sumVectorLower[i];
        return overallSum;
    }

This particular function is part of an open source and free nuget package, HPCsharp, available on nuget.org, which I maintain.

DragonSpit
  • 458
  • 4
  • 9
0

Sure you can (the more important question is - why would you? Just leave it to the runtime; that's its job).

C# lets you map a delegate to a memory address. That memory address can contain raw assembly codes. You can read more on Michael Giagnocavo's blog.

Although I have not tried myself, it may be possible to use Marshal.GetDelegateForFunctionPointer as well.

Filip Frącz
  • 5,881
  • 11
  • 45
  • 67
  • 7
    The runtime may or may not use some SSE instructions but it's not going to vectorize your code. This means you're missing significant performance speedups which may be important to you. – Ade Miller Apr 05 '10 at 01:12
  • Everyone, including MS disagrees with the "why would you" here -- the compiler/runtime can't detect most situations when SIMD instructions make sense for you -- as such, MS's next gen version of the Runtime (RyuJIT) supports developer specified SIMD optimizations straight from C#. -- I get that you posted this answer in 2009, but it's an extremely close minded answer, this sort of mindset should be discouraged by the community in general. – BrainSlugs83 Sep 01 '14 at 23:21