日期:2013-05-21 浏览次数:20450 次
原著:Fahad Gilani
翻译:yy2better
原文出处:MSDN Magazine March 2004(C# In-Depth)
下载此文章的代码 ScientificC.exe (127KB)
本文假定你熟悉 C#
摘要
C#语言在多种项目中应用的相当成功,它们包括 Web、数据库、GUI及其他更多类型项目。有充分理由认为,C# 代码最前沿的应用领域之一很可能是科学计算。但 C# 能达到 FORTRAN 和 C++ 应用于科学计算项目的水平吗?
在本文中,通过研究由 .NET 通用语言运行时决定的 JIT 编译器、微软中间语言和垃圾收集器如何影响性能,作者回答了这个问题。他还论述了 C# 数据类型,包括数组和矩阵,及其它在科学计算 应用中起重要作用的语言特性。
C#语言已获得工作在不同领域开发者的尊敬并在他们中间得到相当的普及。最近两年,C# 在交付健壮的产品中起着重要的作用,从桌面应用程序到 Web 服务,从高阶商务自动化到系统级应用程序,从单用户产品到网络分布环境中的企业解决方案,都有 C# 的存在。假设此语言的强大特性,你可能会问 C# 和 Microsoft®.NET 框架是否能被 更加广泛地用于除GUI和基于Web组件之外的程序中。它是否已准备好被科学团体用于开发高性能数字性编码?
答案并不一目了然,因为首先需要回答一些其它问题。例如,什么是科学性计算(scientific computing)?为什么它不同于传统的计算?语言是否真的具备适于科学计算 编程的特性?
本文中,我会揭示 C# 的一些内在特性,它们允许开发者以轻松、实用的方式使用注重性能(performance-critical)的代码。你将看到 C# 如何在科学 社区中扮演着重要角色,如何为下一代数字计算敞开大门。你也将看到,尽管谣传因内存管理开销过大而使受管代码运行缓慢,但是复杂性适度的代码运行得很快;它根本不会被垃圾收集器中断,因为大多数数字上的处理不会需要足够多的内存释放而导致调用垃圾收集。我将探究 C# 在数字计算世界里是不是一个好的选择。我还将考察一些基准(benchmark),并将结果与非受管 C++ 代码进行比较以便了解在性能和效率方面 C# 处在什么位置。
计算科学
计算机的可用性已经使科学家们更容易地证明理论、解答复杂方程式、模拟3D环境、预报天气和执行许多其它高强度运算任务。多年来,数百种高级语言被研发出来以促进计算机在这些领域的应用(其中 有些是高度专业的并发设计概念框架,例如 Ada和 Occam;有些是昙花一现的计算机科学工具,例如 Eiffel 或 Algol)。然而,有少数成为卓越的科学性编程语言,例如 C、C++ 和 FORTRAN——它们在当今科学计算领域扮演 着主要角色已有相当长的一段时间。
但是,如何确定哪种高级语言用于科学计算呢?一般来说,某种语言要想有资格成为产生科学计算代码的平台,它必须包括的标准之一是提供一套丰富的能被用于衡量性能的工具 ,并且必须允许开发者轻松有效地表达问题域。本质上,科学计算语言应该能生成可以被细微调整的有效的高性能代码。
性能和语言
性能已经成为区分用于科学计算编程语言的关键因素之一。编译器和代码生成技术常常被认为是性能限制因素,但这种假定不完全正确。例如,使用最广泛的 C++ 编译器在代码生成和优化方面做得很好。 有一些微妙之处,它们与代码的效率比起来,通常就不重要了。例如,C++中应避免创建过多临时对象,尤其它是一种非常容易创建未命名临时变量但又不使用它们的语言。可以使用表达式模板达到此目的,表达式模板允许延迟数学表达式的实际运算,直到它被赋值。结果可以避免在运行时招致 巨大的抽象惩罚(abstraction penalty)。
这不是说语言特性是影响性能的唯一因素。当进行语言之间明确的评估以衡量性能和成本时,真正评估的是编译器编写者的技巧,而不是语言本身。如果能从语言、运行时或平台中获取可接 受的性能,那么选择可能紧紧关乎个人所好。
如果你已经体验过 C# 并且正在考虑进行真正的科学计算,那么没必要采用其它语言;C# 绰绰有余。
MSIL和可移植性
与所有其它面向.NET的语言一样,C# 编译成微软中间语言(MSIL),它运行于通用语言运行时(CLR)。CLR 可松散地被描述为just-in-time(JIT)优化编译器和垃圾收集器 的混合物。C# 公开和利用了CLR中的很多功能,所以更细致地研究该运行时的工作机制是很重要的。
科学家的关键需求之一是代码可移植性。科学研究机构和实验室拥有许多平台和机器,包括基于 Unix 工作站和PC。它们常常希望在不同机器上运行代码,以追求更好的结果或因为 某一特定的机器为他们提供一套数据处理和分析工具。然而,达到完全的硬件透明度已不是一个轻松的任务而且不总是完全可能。例如,多数大规模项目开发时使用了多种语言混合 的方法;因此,很难保证在一种架构或平台上可运行的应用程序也能在另一种上运行。
CLR 使应用程序和库可被多种语言编写,这些语言都可编译成 MSIL。然后MSIL可运行在任何支持它的架构上。现在,科学家就可用 FORTRAN 编写它们数学库,在C++中调用它们,使用 C# 和 ASP.NET 在 Internet 发布结果。
不像 Java 虚拟机(JVM),CLR是一个常规用途环境,它被设计用来面向多种不同的编程语言。此外,CLR 提供了数据层,不仅仅是应用层的互用性并允许在语言间共享资源。
目前,可以获得大量能输出 MSIL 的语言编译器。这些语言包括(但不限于)Ada、C、C++Caml、COBOL、Eiffel、FORTRAN、Java、LIST、Logo、Mixal、Pascal、Perl、PHP、Python、Scheme 和 Smalltalk。另外,System.Reflection.Emit 名字空间大大降低了开发 面向 CLR 的编译器的进入门槛。
将 CLR 移植到不同架构是一项正在进行的工作。然而,一份开源实现已由 Mono/Ximian 开发出来,并且可获得 s390、SPARC 和 PowerPC 架构 以及 StrongARM 系统的实现。微软也发布了一个运行在 FreeBSD 系统上的开源版本,包括 Mac OS X。(更多信息请看 MSDN 杂志 2002 July 上 Jason Wittington 的文章 "Rotor: Shared Source CLI Provides Source Code for a FreeBSD Implementation of .NET")
所有这些进展发生在过去的仅仅数年中。假以更多时间,很可能一个全功能的 CLR 将可以适用于所有通用架构。
JIT 编译器是否变得更好?
JIT 编译技术是一种非凡的技术,它为广泛的优化敞开了大门。 尽管当前实现的实际情况是:由于时间限