4 ms·
C# (Microsoft stack, probably other stack, probably other .NET languages) lets you generate or input C# code at runtime, compile it, and run it through the jitt
by ChrisLomont 11y ago
C# (Microsoft stack, probably other stack, probably other .NET languages) lets you generate or input C# code at runtime, compile it, and run it through the jitter as desired. It's nearly trivial to do it. The Regex classes for example create code at runtime to do compiled regular expressions, but I think they do it with emitted IL instead of C# code directly.
All the pieces are there.
- dx211 11y ago.Net provides a couple of different ways to dynamically emit IL, but that's not quite the same as being able to emit your own native machine instructions, though. I think the challenge would be that you'd need to work out a calling convention between the jitted code and the emitted native code, at which point you might as well stick the native code in its own library function and compile or assemble it with a native tool.
- ChrisLomont 11y agoPeople have done this if you dig around. The basic idea is you can assemble arbitrary code into a byte array, then use an unsafe cast and use PInvoke to execute. The calling convention for many platforms has been reverse engineered, but I don't have a link handy. I've used it before to see if it works, and you can do it.
- dsharlet 11y agoThe LINQ expression compiler also lets you generate expressions at runtime and compile them, it's an amazingly powerful feature: https://msdn.microsoft.com/en-us/library/bb397951.aspx https://msdn.microsoft.com/en-us/library/bb397951.aspx
- yaur 11y agoHave you ever seen the jiter use SIMD? Having written some test code that was the simplest use case (multiply an array of floats by a float constant iirc) I have not. C# is a great language, but not for compute bound problems.
- ChrisLomont 11y agoYes, I have seen that. Of course the JITer will not perform the same level of optimizations as the fullblown code generator, but then you can just call that if you like. The new JIT engine does support SIMD [1]. And C# can generate SIMD code using various libraries (I think MS has one, and I know Mono does). And various people have shown how to do fullblown x86 assembly code generation and execution from within C#, but it's fragile. [1] http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-fi...
- jj10 11y agoActually, I just tried it: float[] floats = new float[1000]; float factor = 1.01f; int index = 0; while (index < 1000) { floats[index++] *= factor; } ...becomes... 00007ff8`80a804a9 488d549010 lea rdx,[rax+rdx*4+10h] 00007ff8`80a804ae c4e17a1002 vmovss xmm0,dword ptr [rdx] 00007ff8`80a804b3 c4e17a590524000000 vmulss xmm0,xmm0,dword ptr [00007ff8`80a804e0] 00007ff8`80a804bc c4e17a1102 vmovss dword ptr [rdx],xmm0 This is in VS 2013, compiled with DEBUG off, prefer x86 off, and 'any cpu' as the target.
- tbirdz 11y agoThose are scalar instructions, not the SIMD instructions. With x86_64 the fpu stack operations are basically for legacy purposes only, and normal floating point operations are expected to be done with the SSE/AVX scalar instructions. SIMD instruction used the packed variants of the commands allowing you to multiple say 4 floats in a single instruction.
- pjmlp 11y agoYes, you just need to fulfil three conditions: - Use the new RyuJIT - Make use of 64 bits CPU - Use the vector and matrix classes from System.Numerics