My 3D graphics software, written in C# using SlimDX, does a lot of vector operations on the CPU. (In this specific situation, it is not possible to offload the work to the GPU).
How can I make my vector math faster? So far, I have found these approaches:
Run on Mono instead of Microsoft .NET, because they have SIMD support. Not an option for this project.
SlimGen, a project that injects high-performance maths code at runtime. Unfortunately, the project is not in a usable state yet.
Write a DLL in C++ using a compiler that utilizes SSE instructions. Interop with that DLL from C#.
Are there any other options to accomplish faster vector math in .NET?
Write a DLL using Microsoft Visual C++'s compiler. Use standard C++ with SSE intrinsics and/or OpenMP for the heavy numeric code, with #pragma unmanaged. Use #pragma managed to define a clean C++/CLI API which C# can use.
C++ interop is quite a bit faster than p/invoke. And C++/CLI is the only elegant way to deal with both garbage collected memory and the assumptions of native functions (that memory blocks won't move).
You might find that moving some of the OpenGL calls to C++, and using the C++-allocated memory buffers directly for loading VBOs, etc. also gives a big performance win.
Microsoft just announced support for generating vectorized instructions in their .NET Native compiler thanks to back-end C++ compiler optimizations, and more importantly native support for SIMD vector types in the most recent version of their JIT ("RyuJIT"). See some samples here.
Latest developments in .NET include a SIMD dedicated vector/matrix library called System.Numerics.Vector:
Using System.Numerics.Vector for Graphics Programming
This will be enabled as soon as the new JIT compiler "RyuJIT" will be the default, the announcement is here:
RyuJIT: The next-generation JIT compiler for .NET
So very soon (hopefully 2015) we will have very fast SIMD vectors in .NET without any programming overhead.
If you're in the mood to write assembly code in C#, another option is the NAsmJit project, which is a port of AsmJit to C#. I haven't updated it to reflect the latest changes in that project, but much of the support was quite usable at last check.
Mixing .NET with native code. In this case you will need to have one release for x86 and another for x64. You can see Mixed (Native and Managed) Assemblies [MSDN]
Related
I'm learning about PInvoke to use a C++ library (with C-Style interface) in C#. After reading the documentation and searching Google/StackOverflow for additional information I was wondering about binary compatibility of the native library and .Net. I think I read something somewhere a while ago, but I couldn't find it anymore. And I could not find anything else on this.
When I compile a C/C++ to use in .Net, do I need to use certain configurations like compiler flags to make it compatible for PInvoke? Can I use native libraries made with different compilers in one .Net project, provided these libraries don't depend on each other?
I there anything else I need to know about C/C++ compilation for .Net PInvoke?
I would like to use GCC and CLang with CMake projects to create the native libraries.
P/Invoke has a lot of adaptation capabilities. Also P/Invoke is cross platform (with .NET Core).
However, it's not binary compatible with C/C++, but if a piece of C/C++ code can be used by P/Invoke, it's not dependent on the C/C++ compiler (MSVC or other), or said in another way, it will not be able to use any C++ construct, but it will see all C++ compilers as equal citizens
I know C++ code runs on local machine directly. I also know that we can compile c# code into native code using NGen.exe. My question is
If we use Native code generator NGen.exe to compile c# code into native code, do we still need the .NET framework to run it?
In fact, if you compile your C++ code into a Windows executable you still need Win32 dlls and other stuffs. Your program cannot run on a CPU that does not have anything besides your program.
The same story for C#. If you compile C# to native code, you do not need the JIT compiler, that is part of .NET runtime. But you still need all other parts of .NET runtime.
For example, the .NET framework with all its classes is not linked into your program. If they would put all required .NET classes into your binary, a simple Hello world app would become huge.
You can use mono to build a C# app that has everything pre-compiled with statically linked framework libraries and does not need a separate runtime.
I wouldn't recommend it, though. Not everything is available for static linking, and one of the things about using a JITter is that it makes your code faster on average across all your deployments, as you can now take better advantage of machine-specific optimizations. It's also not something that even mono is set up to do out of the box.
Yes, you need the framework because the libraries your app use come from the framework.
When you use NGen not just your code is compiled on native code, chunks of framework code are 'nativized' too, just the right parts your apps use.
All this doesn't change your assembly (exe or dll) phisical bytes, this compile the IL to native and store this native bytes in compiled assembly cache.
References in compiled assembly cache still needing some framework components, specially to framework core wich is native code from the beggining.
I'm new to C# (but not to programming) and I was wondering: do C# programs always require .NET, or are there ways to avoid dependencies and make the application independent?
Yes C# always requires the .NET runtime.
If you are worried about other platforms there is Mono which will allow .NET applications to run on platforms other than Windows (i.e. Linux) using the Mono runtime.
C# code is compiled into CIL code which is a platform-independent instruction set, I quote from Wikipedia:
During compilation of .NET programming
languages, the source code is
translated into CIL code rather than
platform or processor-specific object
code. CIL is a CPU- and
platform-independent instruction set
that can be executed in any
environment supporting the Common
Language Infrastructure, such as the
.NET runtime on Windows, or the
cross-platform Mono runtime.
A CLI runtime/interpreter is required, but it doesn't have to be .NET.
Currently there is one other CLI interpreter, MONO, for Linux.
C# isn't compiled to native code, and therefore the computer can't read it. You need the .Net framework to convert the so called bytecode (the code that the C# compiler compiles to, CLI) can be converted by the Just In Time compiler of the .Net framework.
Mono is an alternative framework, and it can also run C#. It is supported on more platforms then then the .Net framework (that only supports Windows).
So yes, either the .Net framework or the Mono runtime is needed to run C# applications, new versions of Windows automatically install and update the .Net framework.
Apparently .NET runtime is not required, see MonoTouch for example.
It is possible. C# is just a programming language, and just like any other programming: It can be compiled in any way you can think of: That includes compiling without .NET. In fact, the MONO project (C# for a lot of platforms) does just that.
There are some other commercial compilers available that will pretend to compile your application without .NET , but they just stick .NET in your executable: which is useless, slow and just stupid.
Any other way to use C# without .NET or MONO would be more of an educational experience than a practical solution. As for what the education experience is worth: If you have the time, I would definitely recommend trying something like it when you have a bit more experience.
Just as C programs typically require a C runtime, C# programs require the common language runtime.
I am starting to use Mono to develop applications in C# and C++. I wanted to ask you, how is Mono compiling the C++ code? is it using GCC? It is amazing to see that it has the STL containers... Also, can I use the Boost libraries and GSL libraries with Mono? Thanks in advance!!!
I think you must be using MonoDevelop, the IDE, as opposed to Mono itself.
Yes, MonoDevelop uses gcc/g++ to compile C/C++ source code, but it is not compiled to CIL - it is compiled to a native binary.
If I am understanding correctly, then you should be able to use boost just fine.
If, however, you are asking if Mono has support for Mixed-Mode assemblies or executables (e.g. assemblies/exe's that contain both native and .NET CIL), then I am sorry to inform you that this feature is not supported, nor is compiling C++ to pure CIL by Mono.
As long as you don't need mixed mode (i.e., forget the native part and go for CIL-only), mono does work with C++ code (I hear they're now experimentally supporting mixed mode, on Windows especially, and elsewhere via wine, but I think that part's NOT ready for prime time). The one well-supported C++ compiler at this time is Microsoft C++/CLI on Net 2.x frameworks; efforts have been underway (for many years now) to add gcc, but I don't know of any production-ready result so far:-(.
I have some neural net code written in c# that would benefit from using SIMD support. Mono 2.2 just came out that supports SIMD but Microsoft's c# does not support this yet. Being happy with my c# setup I was wondering if I could write a lib in mono for that piece and call it from .net.
Edit:
I guess what I really want to know is it possible to compile mono down to something like a DLL that I then can call from dotnet. I heard Miguel de Icaza on a podcast saying that for the iphone the mono compiler would allow them to compile down to an exe for moonlight so it did not violate the terms of service for iphone so it got me thinking what else can you compile to.
I heard Miguel de Icaza on another pod cast Herding Code Episode 28 say that you could use the mono complier to compile to an exe not just to intermediate code. What are the implications of this?
This got my curiosity up so I thought that I would throw a bounty at it.
From Miguel de Icaza's blog:
Our library provides C# fallbacks for
all of the accelerated instructions.
This means that if your code runs on a
machine that does not provide any SIMD
support, or one of the operations that
you are using is not supported in your
machine, the code will continue to
work correctly.
This also means that you can use the
Mono.Simd API with Microsoft's .NET on
Windows to prototype and develop your
code, and then run it at full speed
using Mono.
As I understand it, this means that you can write code that uses Mono.Simd, and will be able to run it under .Net, but it won't be any faster than regular code, because the .Net runtime doesn't support SIMD yet.
Essentially, if you write it with Simd and distribute the dll with your code, it will use acceleration if the target VM supports it. If not, it doesn't break. So you can use the library and give any users of your program who run .NET apps with Mono a speed boost.
Microsoft has been said to be planning to add such support in its next release of its runtime, though I cannot find the link and don't have it handy right this sec---can dig the link out of a historic backup if anyone is interested enough.
In order to take advantage of SIMD features, the runtime should be able to natively support it. Basically, Mono treats Mono.Simd namespace specially in the runtime. Obviously, Microsoft .NET runtime does not support this feature. However, the Mono.Simd assembly provided is a completely valid and normal .NET assembly written in managed code and therefore it can run on .NET CLR, but it would be just a software emulation of what SIMD instructions do.
You can run Mono runtime on Windows and take advantage of those features but there is no direct way to run half of application on .NET and the other half on Mono (you could, of course, use communication mechanisms as two distinct applications can use, but it doesn't make sense for this scenario at all).