News for hackers. Stuff that matters.
Re:Introducing .NET IL Linker by pcunite on Wednesday August 30, 2017 @02:56PM (#15134895)
If .NET (using C#) can produce a native binary I'll switch to that for as many projects as I can. Currently I use C++, mostly to interface with the OS. I love the feel I get when working in C#. Everything is so nice and cozy.

Memory: The memory usage "looks" bad. I suppose maybe GC would kick in when it needs to. It has not been a problem for me, but when you see the code in C++ taking 1MB ram and a C# implementation taking 10MB, well, you have to wonder.

Performance: C# performs bounds checking, which I take it is a significant performance hit. I've not had this matter yet, but I've not converted everything over to .NET.

Re:Introducing .NET IL Linker by int_19h on Thursday August 31, 2017 @02:04AM (#15138442)
The nice thing about C# is that, unlike Java, you actually get all the low-level things. They're just tucked away, out of sight of your average coder who's more likely to shoot themselves in the foot with them. But if you know how to use them, it's all there. Let me enumerate.

C# has value types, which follow the same memory model as in C (i.e. stack-allocated for locals, embedded directly into the outer object as fields). You can request explicit layout mode, whereby you can set an offset for every field manually - if you set them all to zero, you get a C union. Alternatively, you can request automatic layout mode, where the JIT is allowed to reorder the fields in arbitrary ways to optimize memory and/or access, which is something you don't even get in C.

It has raw pointers. Unlike object references, these have the usual C semantics - there's no GC involved there, and you're responsible for keeping the objects alive, so you can have dangling pointers etc. No boundary or null checks, either - it's zero overhead. You can do pointer arithmetic on them, including indexing with []. If you P/Invoke malloc or equivalent, this gives you C-style heap allocated arrays.

It has stackalloc, which is a language operator that's equivalent to the non-standard alloca() function in C - allocate a chunk of memory on the stack, and return a pointer. This immediately gives you stack-allocated arrays as flexible as C99 VLAs.

With generics, if a generic type parameter is a value type, the specialization for that type is separately JIT-compiled and optimized. This can be used in a way very similar to C++ templates, for zero-overhead inlined callbacks and similar shenanigans.

All in all, if you want to write high-perf code in C#, you certainly can. You'll hit the limits of the JIT optimizer soon enough - it can't be as good as a full-fledged AOT C++ compiler, say - but you can certainly shed most of the overhead associated with a managed language.

Re:Introducing .NET IL Linker by luch on Thursday August 31, 2017 @03:40AM (#15138780)
You can even wrap native Win32 code in a CLR dll : https://msdn.microsoft.com/en-us/library/ms235281.aspx

The binding is a bit funky (lots of `ref` and `gcnew` keywords sprayed here and there) but it works.

Re:Introducing .NET IL Linker by pjmlp on Thursday August 31, 2017 @02:31AM (#15138545)
In Java some of them are there, although the Unsafe package is not sanctioned, and marked to be replaced by something safer that can provide the same capabilities (e.g. VarHandles on Java 9).

As for the rest at least we can hope Java 10 brings them.

You missed a few C# goodies from 7.0 up to 8.0, coming from the experience with Midori.

Re:Introducing .NET IL Linker by int_19h on Friday September 01, 2017 @05:46AM (#15147213)
The goodies in question are local refs and ref returns, right? Which really only make a difference when you're writing memory safe code. If you're dropping down to "unsafe" and manual memory management for other things, then refs don't do anything that raw pointers don't.
Re:Introducing .NET IL Linker by pjmlp on Friday September 01, 2017 @07:00AM (#15147428)
There are other goodies, like memory views, blittable structs, interior pointers and readonly refs.

https://github.com/dotnet/roslyn/blob/master/docs/Language%2...

Re:Introducing .NET IL Linker by alkonaut on Wednesday August 30, 2017 @05:48PM (#15136349)
> Performance: C# performs bounds checking

It does (The JIT that is), but it also often does not. For example a regular for loop does not bounds check anything. The newer x64 JIT ("RyuJIT") is a whole lot smarter than the legacy x86 jit was.

I imagine that once you start producing proper native binaries using whatever backend you want instead of a JIT that has a requirement of being FAST in addition to making code that is FAST, you can get even more optimization done.

Also, bounds check are becoming cheaper and cheaper as memory fetches become (relatively) more expensive with every hardware generation.

C++ code is usually faster than C# code but bounds checking is probably not the biggest culprit. If you use "idiomatic C#" with reference types, most operations have a lot of memory fetch overhead with pointer chasing etc.

It's possible to write pretty efficient C# code, and it can still look pretty nice. You end up using arrays more, structs more, obviously worrying about AoS vs SoA more. You should also look at the new ImmutableArray types that look like List<T> but have effectively no overhead compared to a plain array. After that comes Span<T>, which makes even more exotic things possible.

Re:Introducing .NET IL Linker by Nuzzerino on Wednesday August 30, 2017 @06:26PM (#15136627)
Using things like stackalloc, malloc, and local-only references, It is possible to implement algorithms in C# which can run at blazing-fast speeds, sometimes hundreds of times faster than idiomatic C#. C#-style arrays would not make the cut.

The optimal thing to do would be to memcpy several KB of data at a time from your heap-based memory, into your stack-allocated memory, do your processing in the optimized inner-loop, then commit the data back to the heap. I had to do this once to increase the throughout of a cluster of image processing servers.

I often scoff at the idea that C# isn't a good choice for performance-intensive tasks.

Re:Introducing .NET IL Linker by alkonaut on Wednesday August 30, 2017 @06:41PM (#15136734)
At some point however, the C# becomes so in-idiomatic or convoluted that it's just C in C# clothing. So one always needs to ask if it's time to just offload a task to a native library. It's convenient to have a single toolchain and not mess with a native toolchain though.
Re:Introducing .NET IL Linker by ygra on Thursday August 31, 2017 @01:13AM (#15138301)
Especially since with native you're giving up AnyCPU, unless compiling the native parts for every platform you care about. I'd also argue that even unidiomatic C#'s semantics are less prone to UB than switching to C.
Re:Introducing .NET IL Linker by Coincoin on Wednesday August 30, 2017 @10:57PM (#15137854)
>If .NET (using C#) can produce a native binary I'll switch to that for as many projects as I can.

We've been compiling our large C# games to native code for some years now because iOS only supports signed code. The main problem is you can never JIT; this creates all sorts of limitations with generics, dynamics, expressions and reflection.

Xamarin has become better and better at handling generics but there are still a couple of things they just can't do anything about.

>Memory

Yes, the memory looks bad because it will not get completely collected until needed. The framework code is big, but that's a flat cost. It might take a little more memory for the runtime up keeping, but it is not 10x. However, memory profiling is a breeze compared to native, so it becomes easier to optimize on a large complicated project.

>Performance

If you don't want to bound check there are a lot of solutions, from simple to advanced. Most of the time we end up just iterating the whole array anyway, and in those case, there are no bound checks.

In the rare case where we really need raw power (graphics, path finding, physics, large file access), we use native code and thin wrap it with P/Invokes.

Re:Introducing .NET IL Linker by srean on Thursday August 31, 2017 @01:19AM (#15138318)
Curious if you deal with a lot of float32 math (the usual sin cos log tanh) and if so what do you use.
Re:Introducing .NET IL Linker by Coincoin on Thursday August 31, 2017 @03:36PM (#15143205)
For the heavy lifting such as scene transformations and animations we delegate in batches to a SIMD optimized native lib.

For the rest, we use System.Math. They are not used enough to be a significant bottleneck.

Re:Introducing .NET IL Linker by ledgerdev on Wednesday August 30, 2017 @08:16PM (#15137201)
> If .NET (using C#) can produce a native binary I'll switch to that for as many projects as I can.

It's coming... https://github.com/dotnet/corert

Re:Introducing .NET IL Linker by 13of40 on Thursday August 31, 2017 @01:43AM (#15138374)
I'm sure there's some reason this isn't the answer, but haven't we had ngen since time immemorial? Aren't all of the assemblies that get shipped with Windows actually compiled to the native architecture?
Re:Introducing .NET IL Linker by int_19h on Thursday August 31, 2017 @01:55AM (#15138413)
NGen is more like a cached result of the JIT output. It was never particularly fast, and in some cases actually worse than normal JIT. The main benefit you gained from it was assembly load times.

And it most certainly didn't do anything about the dependencies on the runtime (VM, GC etc).

Re:Introducing .NET IL Linker by ZenoArrow on Wednesday August 30, 2017 @03:54PM (#15135401)
> "If .NET (using C#) can produce a native binary I'll switch to that for as many projects as I can."

https://docs.microsoft.com/en-us/dotnet/framework/net-native...

Re:Introducing .NET IL Linker by jetti on Wednesday August 30, 2017 @04:52PM (#15135899)
I like how Microsoft added this but the major drawback is it is Windows 10 only.
Re:Introducing .NET IL Linker by pjmlp on Wednesday August 30, 2017 @05:15PM (#15136103)
There is also mono aot as possible alternative.
Re:Introducing .NET IL Linker by jetti on Wednesday August 30, 2017 @05:21PM (#15136149)
Yep, but it isn't quite the same. Mono AOT still requires Mono to run the executable, it just doesn't use the JIT engine (when passing in --aot=full command line when executing your program). It doesn't create a native executable.
Re:Introducing .NET IL Linker by pjmlp on Wednesday August 30, 2017 @05:23PM (#15136163)
Sure it does, how do you think Xamarin creates native executables for Apple devices?
Re:Introducing .NET IL Linker by jetti on Wednesday August 30, 2017 @10:27PM (#15137729)
Oops, you're right. I misread the docs. Sorry about that!
Re:Introducing .NET IL Linker by youdontknowtho on Wednesday August 30, 2017 @07:15PM (#15136917)
they also support command line apps...and linux. its on github.
Re:Introducing .NET IL Linker by judah on Wednesday August 30, 2017 @03:04PM (#15134963)
There's definitely a cost to all that coziness; it's all about tradeoffs. Garbage collection, bounds checks, APIs that trade memory efficiency for ease-of-use, to name a few.

It's not to say that C# will always be 10x memory usage, however, it will always be somewhat higher. Even with a linker, when you run a .NET app, it's not just loading your C# code, but also .NET code that you call into (linker helps keep this slim) and of course the Common Language Runtime C++ code that executes your app and manages its memory.

Re:Introducing .NET IL Linker by svick on Friday September 01, 2017 @05:33PM (#15152555)
> APIs that trade memory efficiency for ease-of-use

This is currently being worked on. With the addition of Span<T>, many APIs will soon have a version that does not allocate and instead use a buffer you pass in (which can be managed or unmanaged).

Re:Introducing .NET IL Linker by snarfy on Wednesday August 30, 2017 @09:23PM (#15137447)
Memory usage is the trade off for having performant garbage collection.

For compilation into a native binary, there is the corert project:

https://github.com/dotnet/corert/tree/master/Documentation

Re:Introducing .NET IL Linker by RachelF on Wednesday August 30, 2017 @05:02PM (#15135997)
Exactly my thoughts. Give me a .NET compiler to a native binary.
Re:Introducing .NET IL Linker by ledgerdev on Wednesday August 30, 2017 @08:20PM (#15137207)
Re:Introducing .NET IL Linker by saltydogdev on Wednesday August 30, 2017 @06:21PM (#15136604)
Check out the Emeddinator. It turns .net assemblies into native libraries.

https://github.com/mono/Embeddinator-4000