`
donsun
  • 浏览: 30006 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

DotNet托管C# VS DotNet托管C# 调用C++本地代码

阅读更多

DotNet托管C# VS DotNet托管C# 调用C++本地代码



1    概要    2
2    开发环境    2
3    名词解释    2
4    方案定义    3
4.1    什么是C#托管代码    3
4.2    什么是C++本地代码    3
4.3    C#托管代码如何调用C++本地代码    3
5    方案比较    4
5.1    Mobile系统瓶颈分析    4
5.2    C#托管代码与C#调用C++本地代码的比较    5
5.3    方案选择    6
5.4    实施过程中的特殊情况    6
6    总结    6
7    参考资料    7

 

1    概要

在Mobile项目中,开发模式的选择对于系统的性能与灵活性起着至关重要的作用,如何在C#托管代码与C#托管代码调用C++本地代码之间做出选择,取决于性能与灵活性的权衡。
备选方案:

  • 纯C#托管代码
  • C#托管代码通过P/Invoke调用C++本地代码

本文将从Mobile项目开发的各个方面讨论两个方案的可行性,最终将推荐采纳其中之一的解决方案使用于Mobile 2中。

2    开发环境

定义开发环境,有利于在基础层面确定可行性方案的支撑平台。

项目 属性 备注
硬件平台 SC32442/PXA270/XScale/TI OMAP 730/750/850等
软件平台 Windows Mobile 5.0 Windows Mobile 2003
开发工具    Visual Studio 2005
开发语言    Visual C# &Visual C++       
移动数据库 SQL Server CE 2003   
.Net Compact framework
    2.0/1.1

 

3    名词解释

  • 托管代码(Managed Code)

所谓托管代码即为中间代码(Middle Language),而非原生可执行代码,不能被处理器直接使用,需要虚拟机与相对庞大的运行时环境(RTE)支持,执行效率偏低,但更灵活且具有更好可移植特性。

  • 本地代码(Native Code)

本地代码指针对特定的操作系统,特定的处理器指令集编译连接的特定的机器指令,无法跨平台移植,也无足够的灵活性,但具有非常高的执行效率。

4    方案定义

首先解释一下C#托管代码与C++本地代码的区别。

4.1    什么是C#托管代码

C#托管代码,Microsoft.Net Compact framework 平台上执行的中间语言编码(Middle Language),由于.Net Compact framework 运行于资源相对匮乏的移动平台,平台的开发商在中间代码的执行效率上作了优化,包括削减运行时库(RTL),即时编译机制(JIT),缩短内存自动回收(GC)周期等方法优化中间码性能,使其性能相对PC平台的.Net Framework有了很大的改善,但是对于移动平台来说其性能还是远远达不到本地代码效率。但其优势也是显而易见的,.Net Compact framework强大支撑平台,丰富的界面元素支持,Windows Mobile的跨平台特性等是本地程序无法比拟的,并且托管代码的开发与集成开发环境(IDE)的完美结合使得快速开发的成为可能。

4.2    什么是C++本地代码

C++本地代码,本地代码(Native)是相对于中间代码(Middle Language)而言的,本地代码指基于特定的处理器指令集编译的,可以直接在硬件平台上执行的原生代码。由于移动平台的资源有限,处理器能力与内存资源的受限,所以Window Mobile 2003之前的的版本是不支持.Net Compact framework运行时环境的,这也是出于运行效率的考虑,毕竟中间代码需要解释器与运行时编译器支持,并且需要一个相对来说比较消耗资源的运行时环境支持,包括垃圾收集器(GC)等。
所有版本的Windows Mobile操作系统都支持本地代码的执行,但对于不同的操作系统与硬件环境,需要编译不同的可执行程序,以使其可以运行于不同的平台上,给软件组件化跨平台部署带来了很大的不便,但本地代码的优势也是显而易见的,本地代码直接运行于硬件平台之上,采用C++编译器其性能是最优的,在Windows Mobile系统中,编写高效率的处理程序,硬件驱动程序或者要求高性能的算法,使用C++本地代码为首选方案。

4.3    C#托管代码如何调用C++本地代码

在一些特殊的环境中,以C#托管代码为主要的开发结构的系统中,有时会有一整块的功能需要高性能处理,例如图形渲染,高精度数值计算等,这就可以采用C#托管代码调用C++本地编写的Dll来实现该需求,.Net Compact framework提供了P/Invoke方式从托管代码中调用非托管的本地Dll,可以很好的解决这个问题,但是Micorsoft表示P/Invoke的性能并不是很好,远远达不到本地代码调用本地代码Dll的性能,所谓P/Invoke的性能不好并非是本地代码的执行效率问题,P/Invoke不会影响到非托管代码的执行,只是调用过程中的开销比较大,也就是说高密度频繁调用小量的高效率代码的代价可能会超过纯粹的托管代码,其效率损耗主要在托管类型与本地类型的相互转换上,以及非托管Dll的加载与释放上,所以使用P/Invoke非常适合足够规模一整块的高效率代码调用,而非频繁的小规模调用,小规模高密度频繁的P/Invoke调用往往在性能上得不偿失。

5    方案比较

经过上面的分析,想必对C#托管代码和C++本地代码以及C#通过P/Invoke方式调用C++本地代码的优劣性都有一定的了解了,本章将针对Mobile 2的具体需求以及系统瓶颈的分析,分类比较其优缺点。
Mobile运行于移动嵌入式平台上,硬件资源的非常有限,使得开发人员对资源合理分配与使用尤为重要,但对于一个设计生命周期相对较长的产品线来说,灵活的框架以及快速开发灵活部署的特性也非常重要,往往效率与灵活的框架是相冲突的,怎么样的权衡取舍,才能得到更加成熟的产品设计呢?首先针对Mobile进行瓶颈分析,确定合理的解决方案。

5.1    Mobile系统瓶颈分析

Mobile 1的项目已经实施完毕,对于嵌入式平台的开发积累下了丰富的经验,下面一组数据更加准确的说明的 Mobile 1性能的瓶颈分布,从而对改善Mobile的设计方案有着积极的影响。

  • 用户变更页面初始化过程耗时分布数据
步骤 耗时(ms)
初始化窗体 17
初始化 控件 32
初始化对象 9
方法调用与参数传 递 1
访问数据库 479
合计 538

 

  • 用户变更页面初始化过程耗时分布图示


由上面的图例及数据显示,Mobile 1中,主要的性能瓶颈在于DB的访问阶段,而Mobile 2的功能定义中,数据库的访问负荷并没有比Mobile 1中有所减少,所以从Mobile 1中的经验得知,Mobile 2的性能瓶颈主要还是集中在DB访问层面,先不讨论Windows Mobile 系统硬件资源优于Symbian,也不用考虑MS SQL Server CE的性能是否优于Oracle Lite,单纯从业务模型上分析,单个业务的相对耗时瓶颈还是在数据库访问上,因为Mobile 2中并不包含耗时算法或者复杂运算,所以如何改善DB性能决定了整个Mobile 2的整体性能,而作为程序设计语言来说,对系统整体性能的影响是相当微小的。

5.2    C#托管代码与C#调用C++本地代码的比较

下面针对两种模式进行针对性的对比,并进行感官评估打分,为Mobile 2的架构模型选择提供参考数据。

对比项目 C#托管代码 C#托管代码调用C++本地Dll
执行效率   3 5
可以执行    5 2
开发周期 5 3
代码可重用性 5 2
DB访问性能能 5 5
跨平台支持 5 3
MUI多语言支持 5 5
运行时多态性 5 2
界面的灵活性 5 3
合计 43 30

注:得分高代表该对比项目优秀,反之亦然

5.3    方案选择

由上面图表可知,C++本地代码的效率高于C#托管代码效率,但由于Mobile 2中整体系统的瓶颈并非在于可执行程序的算法上面,而是IO方面的性能损耗非常大,并且C#托管代码访问数据库与C++本地代码访问数据库的性能是相同的(使用的是同一套SQL Server CE的API),那么如下方法可以计算出两种方案的性能差距:
DB访问占整体耗时比例:479(DB访问耗时) / 538(完整业务耗时) = 89%,那么C#托管代码的效率与C#托管代码调用C++Dll的效率的区别仅仅在于另外的11%中,如上图中数据显示,C#调用C++Dll的方法仅能对系统整体性能中的11%提升40%左右,既然数据库的访问时间是固定的,那么C#托管代码调用C++本地代码的效率最高能够提升4.4%,这是一个微乎其微的数字,为了这4.4%而损失.Net Compact framework众多优良特性是非常不值得的。

综上所述,纯C#托管代码的的综合特性优于C#托管代码通过P/Invoke调用C++本地代码,

5.4    实施过程中的特殊情况

由于实施过程中,不可预知的特殊情况时有发生,为了满足不同的且特殊的需求,.Net托管代码通过P/Invoke方式调用C++编写的高效率本机代码仍然是一个不错的解决方案,由于P/Invoke属于.Net Compact framework 包含的特性,不需要另行的开发与部署即可使用该功能,所以,Mobile 2的开发过程中并不排除特殊情况使用该特性的可能。

6    总结

.Net 的优秀特性在于其丰富的运行时库支持,方便高效的开发模式,以及及时准确地垃圾收集机制,高效的即时编译特性能够有效地提升系统整体能能,跨平台支持,可以使程序集一次编译后跨平台部署,丰富的分辨率敏感自动停靠控件可以使开发人员不必维护屏幕分辨率不同给界面带来的影响等,这些优良特性使得.Net Compact framework托管代码的优势显而易见,微软的FAQ中也提到,企业级应用并不涉及复杂高负荷预算时,使用.NET Compact Framework开发即可满足性能需求,即便相较本地代码的执行效率会有所损失,但这样可以获得最好的灵活性和可移植性。

7    参考资料


• Microsoft .NET Compact Framework 开发常见问题解答
http://www.microsoft.com/china/msdn/library/NetFramework/netcompactframework/understandingnetcfFAQ.mspx

• 了解如何使用 .NET Compact Framework 的平台调用 (P/Invoke) 功能:
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfintrointerp.asp

• 了解如何使用 .NET Compact Framework 在托管和非托管代码之间封送数据。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfmarshallingtypes.asp
 
• 了解如何使用 dumpbin.exe 作为在基于 Microsoft .NET Compact Framework 的应用程序中声明 P/Invoke 的手段。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/netcfdumpbinpinvoke.asp

  • 大小: 43.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics