.NET Core CLR Questions!


#1

Read the whole thing post from: http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducing-net-core.aspx

I’m so exited to take a look at the CLR part when its released.

I have couple questions:

  1. Will any of this .NET Core stuff be used in .NET Micro?

  2. What kind of memory constraints would .NET Core have? (Could it replace .NET Micro).

  3. Will porting .NET Core CLR to other CPU types like MIPS, PPC ect be an easy task?
    3.3) Will porting to asm.js/NaCl/WebGL for IE, Firefox, Chrome, ect be doable? How much of the CLR has CPU specific instructions?

  4. Can I embed .NET Core and invoke the runtime like I can with “Embedded Mono”?

  5. Will .NET Native be open sourced as well so we could port it to other platforms and CPU types? (This would be important to compile .NET on iOS).


#2

Good questions.

Will any of this .NET Core stuff be used in .NET Micro?

A major goal of ours is consistency across .NET implementations. .NET Micro is part of that vision. Micro has very different design constraints than .NET Core. It’s intended for devices w/o an OS. We’ve typically found that the two implementations need to be different. It’s probably worth a new conversation with the .NET Micro team, as its been a while since we validated that assumption.

Both projects are now open source. It makes sense to message to the community where code sharing makes sense. I’ll reach out to the .NET Micro team on that point.

What kind of memory constraints would .NET Core have? (Could it replace .NET Micro)

Unlikely, for the reasons given above.

Will porting .NET Core CLR to other CPU types like MIPS, PPC ect be an easy task?

Porting a development platform that directly touches hardware to another chip is never easy. Chip architectures often differ quite a lot. A naive port can be straightforward, but then optimizations may need to be re-written since chips work differently. That’s necessary for decent performance. Memory consistency is a chip characteristic where Intel and ARM differ, for example.

Will porting to asm.js/NaCl/WebGL for IE, Firefox, Chrome, ect be doable? How much of the CLR has CPU specific instructions?

There are projects to convert MSIL code to JavaScript/asm.js, but no-one has every (to my knowledge) tried to convert a .NET runtime to asm.js. I suspect that you wouldn’t try, since browsers have very competent runtimes at this point. The MSIL to JS route seems like the best approach here.

Can I embed .NET Core and invoke the runtime like I can with “Embedded Mono”?

The CLR has had a public hosting API since its inception. SQL Server and IIS are great examples of CLR hosts. CoreCLR also has a hosting API, which ASP.NET 5 uses. This will be included in the CoreCLR repo, when it shows up.

Will .NET Native be open sourced as well so we could port it to other platforms and CPU types? (This would be important to compile .NET on iOS).

Right now, we are focussed on CoreCLR. I can imagine .NET Native following. Right now, CoreCLR has all of our attention, so we’ll re-visit the .NET Native question after we’ve got CoreCLR on GitHub.

.NET Native is sufficiently flexible that it could be updated to support additional architectures and be integrated into a compiler toolchain like LLVM. It already supports X86, X64 and ARM. That on its own is suggestive that it has been built with a sound architecture w/rt supporting multiple processor types.


#3

but no-one has every (to my knowledge) tried to convert a .NET runtime to asm.js

FYI this is not true as Unity3D has started to make IL2CPP (and will work on IE later) (Here is the post: http://blogs.unity3d.com/2014/05/20/the-future-of-scripting-in-unity/). Which is a .NET runtime for asm.js. Which is way faster then MSIL to javaScript like (http://jsil.org/)… asm.js or NaCl are the only ways to get performance from games in the browser. javaScript not being strong typed is pitifully slow at optimizing itself in comparison.

Seems like having a CPU agnostic (not platform agnostic) build of .NET even if less optimized might be extremely useful (at least I could make use of it).

Thanks for the answers though, I appreciate it.


#4

@zezba9000 - I’m familiar with IL2CPP and know the folks on the Unity Scripting Team. Smart guys for sure. I was even thinking about IL2CPP when I wrote my reply.

There are two things I was thinking about when I replied:

  • The IL2CPP runtime is very specific to their scenario. It is very possible that they compile their runtime to asm.js. It is unlikely that one would be successful with this strategy with a generic runtime, like .NET Core or Mono. That said, I’d be happy to be proven wrong on that.
  • JavaScript already has a GC. I would have expected that the IL2CPP GC was not used in this scenario.

I’ll ask the scripting guys if they can reply.


#5

asm.js does not have or use a GC as it compiles pure C++ code via emscripten (thus you can use any supported C/C++ GC). IL2CPP uses the boehm gc. I’m a pretty heavy Unity3D game and plugin developer myself. I don’t know what the complications .NET Core will have with asm.js, but Mono can run in NaCl which is CPU agnostic, so I don’t see any reason .NET Core can not be made to do the same. I’ve also started my own project using Roslyn that converts C# AST to native C++ with a super basic GC that could in turn be compiled on any CPU and any platform (simple hello apps work so far on windows) [brought it up as its another solution to getting C# code on more platforms at native speeds].

On the Unity post: http://blogs.unity3d.com/2014/05/20/the-future-of-scripting-in-unity/
Search for:

“While we have an implementation of Boehm supported using this API, we are actively pursuing other options for garbage collection”.


#6

Unity IL2CPP developer here. A few points.

Running .Net code on a target platform really consists of two parts. First, a runtime is required to provide access to services like garbage collection, the type system and metadata, and native resources like files/sockets/threads. Second, some mechanism to run the IL instructions is needed. This could possibly be an interpreter, a JIT compiler, or an AOT compiler.

NaCl is a sandboxed environment, but it allows for machine code to be generated at runtime by the mono JIT. While you could try to target javascript with a JIT (output being JS rather than machine code), Unity took the approach of writing an AOT compiler (IL2CPP). We convert IL into C++ source code to optimize for portability and performance. There are the normal restrictions all AOT compilers encounter, like not being able to generate code at runtime. This means we don’t support any APIs from System.Reflection.Emit. However, our goal is for IL2CPP to be a standard .Net runtime and support the same feature set as Mono AOT or .Net Native.

In the specific case of WebGL/Javascript/asm.js we do compile the Unity engine, the IL2CPP runtime, and the converted C++ into javascript using emscripten. We use the Boehm GC (also compiled to JS using emscripten), not the built in javascript GC. This is because the managed objects from our runtime are not exposed as Javascripte objects.

Lastly, you mention converting the C# AST into native C++. We initially took this approach. I think it’s valid for a number of use cases, although I believe converting IL is more robust and allows for supporting any language that targets (or modifies) .Net assemblies.


#7

Out of curiosity did you guys try existing MSIL/C# to JavaScript solutions like JSIL? If so what did your tests show?


#8

@Shmuelie
Yes I ran tests with my ported RayTraceBenchmark: https://github.com/zezba9000/RayTraceBenchmark/blob/master/C%23/Results.md
— It ran about 10 or more times as slow, but I forgot to post the results when I ran it (like 27-40 mil-sec I think).

@joncham

Lastly, you mention converting the C# AST into native C++…
…although I believe converting IL is more robust

– Correct me if i’m wrong, but I started looking into Mono.Cecil to convert IL to C++ but realized it would be much slower as MSIL is very un-optamized all by itself as it constantly wants to put stuff on the Stack and remove it when it could be using a register instead (MSIL basically assumes your CPU doesn’t have registers it appears). Thus if I don’t do a bunch of optimizations and CPU specific stuff its going to be much slower. My approach I have working partially is as fast as C++, not almost as fast, but as fast and no CPU specific stuff required. Its a direct translation of C# code blocks with a basic GC that could be made to do trickle collections and only run a particular amount of time per game update call. (Nimrod lang does this and you guys said you were looking for better ways to do things with the GC, this would be one of them.) [As a cool side note, I could have the C# to C++ converter compile my code on 8-bit-16-bit CPUs and low mem devices, maybe i’m crazy but I thought that was cool]

But you are correct you would not be able to use langs like UnityScript/Boo ect which are totally limited in comparison to C# and others and I have no desire to use them for anything. In fact it almost makes Unity development harder having them as lib reference loops becomes an issue… but thats a different issue and not to big of one.

A quick question for you, feel free to ignore it if its considered a private topic but is the Unity dev team planning or considering taking advantage of .NET Core in the future when its working? (Guess your answer will be something like you are always keeping options open, but thought I would ask anyway…) [maybe a question better suited for the Unity beta forums]


#9

CIL doesn’t assume anything about the CPU, that’s the point. If it did, it wouldn’t be as portable.

If you’re compiling IL to machine code for some CPU, it’s your responsibility to use registers for values on the IL evaluation stack as much as possible.

If you’re compiling IL to C++, you will have to translate stack manipulation into expressions (e.g. the CIL code ldloc a ldloc b ldloc c add mul could be translated to C++ as a * (b + c)) or you’ll generate code with lots of temporary local variables and rely on your C++ compiler to enregister them.

So, no, I don’t see how converting IL to C++ is going to be much slower than C# to C++, at least on this low level.


#10

CIL doesn’t assume anything about the CPU, that’s the point. If it did, it wouldn’t be as portable.

But it could assume most commonly supported things and if those features aren’t supported the JIT could do conversions fallbacks instead. An alternative at least I would think… but maybe thats a bad idea idk.

the CIL code ldloc a ldloc b ldloc c add mul could be translated to C++ as a * (b + c))

So with your example above, that execution order in the IL would translate to the C++ example?
Like I mean they would appear in the order “ldloc a ldloc b ldloc c add mul” in Mono.Cecil?
Are there any docs that give example of how the IL execution order works? Is it just assumed “add” will take the last two ops and “mul” will take the last two unless its last one is “add” it will skip the ones “add” is using?


#11

Yes.

The authoritative reference is ECMA-335, but that’s probably not a good place to start. Not sure what is a good introduction to IL.

No, add, doesn’t take “ops”, it takes values from the evaluation stack. The spec describes it this way:


#12

Thanks for clarifying, Jonathan.


#13

Ok thanks for correcting my misunderstanding about MSIL.
And thanks for all the other great answers, I think I learned something valuable today :slight_smile:


#14

Yes, we plan on making use of .Net Core when it’s available. Probably as part of our .Net upgrade plans.


#15

I wasn’t the one who ran the tests with existing IL/C# to JavaScript, so this is a bit second hand. I believe the initial results were that they were functional, but not quite as robust as we needed to support our many (millions of) developers. Additionally, targeting C++ and then JavaScript via emscripten allows us to 1) reuse all this work for other platforms 2) output super fast JavaScript via asm.js.


#16

hey @richlander, I was pretty excited about the hosting API, but now I’ve explored it I’ve found that it’s not much use at all. The only interoperation between the host and the managed code is invoking managed functions from the host that specifically have a string argument and return int. No other communication is possible at all.

Does Microsoft still recommend we use COM for native/managed interop?


#17

Just recovering from my first serious foray into UWP/.net Core. I’m not sure where else to ask this question.

Are you going to address deficiences in implementation of reflection/Linq expresssions/Reflection.emit anytime soon on .net native?

On-the-fly-generation of code is non-existent for all practical purposes on UWP and .net Core. Reflection.Emit is completely absent; applying reflection to generic types and methods is impractical in practice unless you only use generics on a handful types that can be presciently pre-declared in rd.xml files; and Linq expressions are (as I understand it) interpreted not compiled, in the current .net Native implementation, and therefore substantially less useful than they used to be; and they suffer from all the same problems with generics that reflection does.

I stlil don’t entirely get the relationship between .net Core, .net Native and Universal Windows 10. A quick glance at the .net core source tree indicates that Relfectiion.Emit APIs are present and implemented (although I haven’ dug deep into the actual implementation. But I have found no serious discussion about this problem anywhere (other than a long horrible unreadable page about how to build .rd.xml files, which is a band-aid solution, not a real solution).

Is this stuff going to fixed in UWP any time soon, or should I just abandon all hope, and backport what I have to WPF (where it started)?

My current application is a ,net bsed computer audio synthesis language that would run nicely on tablets were it not for the rd.xml/.net Native thing. EVerything works fine in debug mode. But in release mode, things are unfixable.

Lack of dynamic code generation is – in my opinion – a huge issue. Time and time again, dynamic code generation, whether via reflection.emit (or preferrably) via Linq expressions provides the glue that works around deficiencies in c#/.net generics. Without this feature, .net/C# is (i think) an unblanced and broken language system.Things that are acheivable with runtime code genration that are now poisonously difficult: mocking, serialization, remoting, run-time code generation, contract programming test frameworks, common use cases for generic types, .net languages, F#. And much more.

For what it’s worth, Reflection.Emit is ONLY needed to generate types of the fly with user-defined fields/properties. Linq expressions have gradually increased in power over the last few years. Whereas Linq Expressions original covered only expressions, they now cover statements, conditionals, code blocks, everythign right up to the method level; but there’s till no way to generate methods in a class built at runtime (except for Dynamic classes); and still no way to declare class-level constructs. Hint hint: it would be really nice if somebody went back and finished that work, so we don’t have any compelling need for Reflection.emit (which is orders of magnitude ore difficult than Linq.Expressions. IF the concern is security, a Linq Expression-style implemention of runtime type building would be fabulous – and would provide some mitigation of the security horrors that Reflection.emit unleashes on a platform.

Any clarifications on the roadmap for this much appreciated


.NET Foundation Website | Blog | Projects | Code of Conduct