如何看待 .NET Native,真能达到 C++ 的性能、C# 的生产效率吗?

软件工程师、主攻高级编程语言虚拟机的设计与实现

360 👍 / 19 💬

问题描述

Microsoft .NET Native FAQ
Getting Started with .NET Native
.NET Native 会给 Windows Store App、Windows Phone App 多大帮助?
.NET Native 会不会跨平台支持 Linux、OS X 等系统?

相关问题:如何评价微软推出的 .NET Native? (知乎的搜索……)

我对.NET Native抱着很大的信心,相信它能让许多C#应用接近用C++写的Windows Store Application的性能。“接近”可能是90%、95%性能,但彻底“达到”100%的C/C++性能还是不太现实。

我觉得这个问题可以参考一下我回答的一个关于Java的静态优化的问题:

逃逸分析为何不能在编译期进行? - RednaxelaFX 的回答

.NET其实也有类似的问题,不过严重程度没有Java那么糟糕。

Java的动态加载是在Class文件级别,所以安全的做静态分析和优化的边界也就在Class文件内;

.NET的动态加载是在Assembly级别,而一个Assembly已经包含了许多类型,虽然静态分析和优化的边界在Assembly内但已经可以做很多实用的优化。

而进一步拓展优化的边界就需要“放弃”一部分动态加载的灵活性,换来更大的可静态分析的范围以便进行更彻底的优化。

在.NET Native之前,.NET已经有一个AOT编译器——NGen,用于在目标机器上把MSIL编译到native code并缓存在GAC里。那.NET Native是不是只是NGen旧瓶装新酒、换汤不换药呢?

从概念上说,完全不是。

NGen的目的主要是通过事先编译(AOT)避免(减少)在运行时JIT编译,提升启动速度和后续运行的性能稳定性,但不是提升程序的平均或最高性能。这使得它的设计和实现有所取舍:

.NET Native的目的则是提升程序性能和简化部署,使得它跟NGen采取了不同的取舍:

(图片截取自Andrew Pardoe的演讲:

.NET Native Deep Dive

总之.NET Native概念非常好,最终效果好不好就看M$同行们有多努力了哈哈哈 ^_^

===================================

@Thomson

大大在回复里问NGen生成的代码是PIC的引用资料,有这些:

CLR Inside Out: The Performance Benefits of NGen.Improvements to NGen in .NET Framework 4
Surupa Biswas: CLR 4
Throughput of NGen-compiled code is lower than that of JIT-compiled code primarily for one reason: cross-assembly references. In JIT-compiled code, cross-assembly references can be implemented as direct calls or jumps since the exact addresses of these references are known at run time. For statically compiled code, however, cross-assembly references need to go through a jump slot that gets populated with the correct address at run time by executing a method pre-stub. The method pre-stub ensures, among other things, that the native images for assemblies referenced by that method are loaded into memory before the method is executed. The pre-stub only needs to be executed the first time the method is called; it is short-circuited out for subsequent calls. However, every time the method is called, cross-assembly references do need to go through a level of indirection. This is principally what accounted for the 5-10 percent drop in throughput for NGen-compiled code when compared to JIT-compiled code.

<- 这描述的就是一种PIC概念的实现。在较新版本的NGen中softbound dependencies仍然是这样实现的,而新的hardbound dependencies则试图把地址硬编码进来。