微软又牛逼产品:.NET Native:C++的性能 C#的产能? - TOMMYHU - 专注互联网开发及运营技术,提供相关资料及软件下载,奇趣网络时事评论!
Apr 16

微软又牛逼产品:.NET Native:C++的性能 C#的产能? 不指定

tommyhu , 21:18 , ASP.NET , Comments(0) , Trackbacks(0) , Reads(3847) , Via Original Large | Medium | Small
微软隔段时间一个产品,和苹果一样,6要出来了,土豪金马上就要out了,不赶紧搞起来,更待何时,一起来看这东东:.NET Native
Highslide JS
Quotation

4月4日消息 国外媒体报道,今日微软宣布了 .NET Native的开发者预览版,这一技术之前被称为项目N(Project N)。简言之,.NET Native把 C#语言编译成原始机器代码,使得它能够像C++一样运行。“云服务器里的编译器能够利用在线商店里的.NET Native编译应用程序,从而根据应用程序所安装的设备,创造定制化的独立应用程序包。”微软在周三发布的博客中这样解释道。去年秋天在Visual Studio2013的发布会上,微软曾简短的展示了.NET Native。
“现在发布的.NET Native预览版本使得你能够利用C#的创造力达到C++的性能,它结合了两种语言的最优化。”
刚发布的开发者预览版使得开发者能够利用Visual Studio在ARM架构以及 x64架构上为Windows商店开发应用程序 。虽然预览版只适用于Windows商店应用程序,但微软表示计划“开发和改善一系列.Net应用程序的原始汇编。”
微软本身已经利用.NET Native开发了某些Windows商店应用程序,包括拼字游戏和Fresh Paint,执行主管这样说道。微软并未透露最终版本的.NET Native的发布时间。

.NET Native首页:http://msdn.microsoft.com/en-US/vstudio/dotnetnative
.NET Native发布的blog:http://blogs.msdn.com/b/dotnet/archive/2014/04/02/announcing-net-native-preview.aspx
.NET Native官方论坛:http://social.msdn.microsoft.com/Forums/en-US/home?forum=dotnetnative
英语可以的话,听听项目的lead怎么介绍的:http://channel9.msdn.com/Shows/Going+Deep/Inside-NET-Native

这里简单讲一下.NET Native的基本架构,基本内容和上面那个talk其实差不多,只是简单给大家讲一下.NET Native的一些基本概念。如果大家有对某个部分具体感兴趣,也可以提出来,我尽量在我能力范围内解答(毕竟不是我一个人做的,呵呵)或者写新的Blog详细解释。

.NET Native和之前的NGEN有本质区别。NGEN实际上是把CLR运行时的数据结构和代码给一锅端(当然,这个是简化的说法,实际上比这个复杂)的放到最终的PE里面去了,运行的时候还是需要整个.NET Framework支持,而且不能避免JIT。.NET Native是全新的技术,整个.NET Framework经过refactoring重写,最终的runtime非常小,只有数百K,无需任何安装(除了mrt100.dll之外,大家可以理解成msvcrt.dll)。大部分的功能都从runtime中refactor到framework中作为C#代码或者作为toolchain一部分存在。一个典型的例子是:P/invoke原来是由CLR实现,使用C++和汇编编写。而现在是经由MCG这个工具接手,直接生成C#。最终.NET Native生成的EXE/DLL是可以直接运行的机器码(通过C++编译器后端生成)。对了,有些朋友可能会问:我们是不是直接生成C++代码?答案是否定的。我们所使用的C++编译器后端接受IL作为输入,生成MDIL。


整个Toolchain(工具链)大致可以分为下面几个阶段:


App IL + FX -> MCG -> Interop.g.cs -> CSC -> Interop.dll -> Merge -> IL transform -> NUTC -> RhBind -> .EXE


第一步:将应用程序的IL代码和整个.NET Framework BCL的IL一起作为输入给MCG。MCG (Marshalling Code Generator)这一块主要是我在负责。这个工具负责检查程序和BCL中所有的Interop相关的类型,比如WinRT接口,P/Invoke,等等。MCG都会为之生成C#代码。这个C#代码是可以直接调试的,有兴趣的朋友可以F11试一下看看。C#代码的作用主要是替代Windows.WinMD中的WinRT类型定义,P/invoke定义,等等,添加各种类型的转换代码,比如字符串类型,RCW和CCW,等等,最终直接调用到本地代码。可能有些朋友会问道:为什么要生成C#? 原来的CLR是直接在运行时生成IL代码的,但是显然这个方法在.NET Native不太适用,而且IL代码很难调试。C#既方便大家调试,也方便我们快速的修改生成的代码,添加更多的功能。(写C++程序生成IL代码可是比较麻烦的,得人工算好stack的位置)
第二步:MCG生成的C#代码通过CSC编译,生成PE文件。这一步没啥可讲的。
第三步:这个PE文件被打包合并到应用程序和BCL,生成一个IL代码的集合。为下一步做好准备。
第四步:这个IL代码的集合会被经过若干的步骤处理,每个步骤都相对简单,只做一件事情。这些步骤的主要作用是提供原来CLR运行时提供的功能,最终的目的是使之最后的代码能够被C++最后编译。在原来桌面版本的CLR里面(也就是4.5里面的那个),很多功能是由Runtime来提供,比如Delegate.Invoke,比如interop。这些Transform的作用是对代码进行处理,把原来需要runtime实现的部分用实际代码替换掉。举个几个例子:

1. 当你在调用Windows.UI.Xaml.Controls.Button类型的时候,MCG也会生成一个对应的Button类型,然后IL Transform会将两者进行替换,这样程序调用的Button类型就是MCG生成的代码了。

2. 当你在进行Serialization和Deserialization的时候,IL Transform会调用另外一个工具SG来生成serialization/deserialization的C#代码,最终这些操作都有这些C#代码生成。
3. 你的程序多半不会用到整个BCL。IL Transform中会有一步叫做Dependency Reducer,使用类似GC的算法(mark->sweep),去掉不需要的代码。MCG也和DR通力合作,减少不必要的interop代码生成。DR也会读取RD.XML文件,决定那些类型需要反射信息,那些不需要。RD.XML这一块我们还在改善之中,也希望大家多提宝贵意见。

其实呢,MCG其实也是IL Transform的一部分,只不过它实际上不Transform而已,而是直接生成C#。


第五步:NUTC对IL进行处理,生成MDIL。NUTC就是传说中的C++的编译器后端的一个特殊版本,优化什么的就靠它了。最后生成的MDIL接近机器码,但是也包含一些抽象的类型信息,需要进一步处理。
第六步:RhBind负责对MDIL进行处理,将里面和类型系统相关的信息生成代码,最后生成一个EXE。其实最终是一个EXE+DLL,实际的代码都在DLL中。EXE只是起到Bootstrap的作用。选用DLL的原因是我们需要支持作为Background Task在Broker里面加载。

几个我听到的常问的问题(如果有些答案过于“官方”,请谅解):

1. 你们最后是生成C++代码吗?

答:不生成。C++后端直接从IL转换成MDIL。

2. WPF支持吗?

答:暂时不支持。目前暂时只支持Windows Store Apps

3. 这个会支持桌面程序吗?

答:目前暂时只支持Windows Store Apps

4. 这个支持JIT吗?
答:目前.NET Native不支持JIT,所有代码都是编译时候生成。

5. 既然是本地机器码,为什么还可以支持类型反射(reflection)?

答:机器码和反射并不冲突,我们在PE文件中储存了额外的用于反射的信息,然后动态读取此信息进行调用。C++也可以支持反射(RTTI),只是不如.NET强大而已。

6.这个需要安装.NET Framework吗?

答:开发编译的时候需要,运行时不需要。

7.为什么不支持VB

答:VB本质上和C#都是生成IL,技术上非常类似。只是目前我们因为时间问题,暂只支持C#。

8.为什么启动运行速度会变快?

答:一方面归功于C++的优秀的编译器后端,一方面也因为runtime的重写和简化。


这次就大概讲这么多。欢迎大家试用一下.NET Native,去下面几个地方给我们提一下意见
▲返回顶部

Add a comment

Nickname

emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot