就在这个月,负责微软Developer Devision工作的微软全球副总裁Soma先生写了一篇博客介绍Visual Studio 2008和即将发布的Visual Studio 2010中支持并行程序开发的一系列工具。在这篇博客(中文翻译版)中,Soma先生不仅介绍了用于开发MPI程序的MPI debugger,还介绍了用于开发Windows HPC Server 2008中集群面向服务架构(Cluster SOA)应用的SOA Debugger插件。在我们前面一篇博客中已经对MPI Debugger的功能做了介绍,其实SOA Debugger也是我们小组努力工作的成果。通过本篇博客,我想请大家和我一道预览即将发布的HPC SOA C# Cluster Debugger插件。
大家知道集群面向服务架构是我们随Windows HPC Server 2008的发布而新推出的并行应用架构和编程模型。通过集群面向服务架构,我们可以把原先运行在单机上的WCF应用扩展成运行在`Windows HPC Server集群环境中的并行应用。要创建一个SOA应用程序大致上需要经历以下的三步:创建服务(WCF Service);将服务部署到集群中;创建客户端应用。如果我们想调试包括客户端和服务在内的整个应用,还要加上如下的步骤:1)在运行服务的计算节点上安装并运行远程调试器(msvsmon.exe);2)在Visual Studio中运行并调试客户端程序;3)在SOA会话(SOA Session)被创建以后,将Visual Studio调试器附加(attach)到计算节点上的服务宿主进程(HpcServiceHost.exe)上从而调试服务进程。这样调试一个SOA应用一共需要3+3=6个步骤,这还不包括每次修改服务的代码还需要重新执行服务部署的过程。听上去是不是很复杂?别急,下面随我看看SOA Debugger如何为你简化SOA应用开发和调试的体验!
安装SOA Debugger插件后,在Visual Studio的新建C#项目的对话框中,我们看到了一个新的项目类型:SOA Client。没错,就是它了!
建立一个SOA Client项目并把它命名为MySOAClient。在我们研究这个新项目之前,还是让我们进行SOA开发的第一步:创建服务程序。大家知道SOA服务程序其实就是一个WCF服务,你可以把现有的WCF服务项目添加到刚刚的MySOAClient解决方案中,也可以在这个解决方案中新建一个WCF服务项目。在我的示例中,我在解决方案中新建了一个叫“EchoService”的简单WCF服务。在创建完服务之后,让我们跳过下一步“将服务部署到集群中”,因为下面我们将看到SOA Debugger可以自动帮我们完成服务部署的工作。
下面让我们回到客户端项目来创建客户端应用程序。大体上编码SOA客户端程序和编码普通的WCF客户端程序比较类似,在此就不一一赘述,具体信息大家可以参看Cluster SOA架构白皮书。客户端编码完成之后,我们还需要对项目的一些属性进行设置才能进行集群上的调试工作。在Visual Studio的解决方案浏览器中右键点击MySOAClient项目,点击属性打开项目属性页面,如下图,
我们可以看到这个项目比一般的C#项目多了一个SOA Settings的属性标签。在SOA Setting的属性页中,我们首先在Head node下拉列表中选择我们的集群头节点名。这里的头节点名必须与我们在客户端代码中创建的会话启动信息相一致。比如在我的代码中,
……
SessionStartInfo startinfo = new SessionStartInfo("SHPC-0052", "EchoService");
于是这里我就选择头节点为“SHPC-0052”。接下来我们需要在Available service列表中勾选需要调试的WCF服务。在这个列表中会列出当前解决方案中的所有WCF服务类型的项目,我们只需要选择客户端代码调用的服务(或者多个服务)即可。这里的服务名和服务项目名称以及会话启动信息中的服务名都应该是相同的(在这里是“EchoService”)。除了头节点名和被调试的服务以外,其他的属性都有合适的默认选项,我们暂时不要改变它们的设定。好了,调试的准备工作全部完成了,让我们开始调试吧!
首先将MySOAClient项目设置为调试的启动项目,随后我们在客户端程序创建SOA会话(Microsoft.Hpc.Scheduler.Session.Session.CreateSession(startinfo))的代码后放置一个断点。按“F5”启动调试器,MySOAClient程序会运行到CreateSession()之后中断。这时SOA会话以及SOA服务job已经创建完成了,让我们来看一看Visual Studio是不是已经附加到所有的服务进程上。从调试菜单打开进程工具窗口,我们可以看到,
Visual Studio调试器已经附加到所有的服务宿主进程上。WCF服务部署,远程调试器的启动以及附加远程进程的工作都被SOA Debugger自动完成了,是不是有WOW!的感觉呢?既然我们已经完成了服务进程的附加步骤,我们就可以直接调试WCF服务的代码了。所有现有的调试器功能我们都可以使用,包括在在服务代码的断点上中断,F10/F11的单步调试,表达式求值(Watch)以及条件断点等等。当调试结束后,SOA Debugger还会自动完成服务的清理工作。
我们已经完成了整个SOA开发/调试的过程,回头看看是不是很简单呢?原先的六个步骤最终被简化为:1)创建服务;2)创建客户端程序并设置SOA调试选项;3)F5!这三步,是不是很简单呢?
以上就是对SOA Debugger的简介,SOA Debugger中还有很多很cool的功能,包括:调试不在Visual Studio解决方案中的WCF服务; 为被调试的服务部署额外的文件;只调试运行在特定计算节点上的服务;只调试某些特定的服务请求(Service Request)。对于这些功能我就不一一介绍了,我期待你试用我们即将发布的SOA Debugger之后自己亲身体验所有这些实用的功能!我们的开发工作还在进行之中,在最终发布之一定还会有一些改动,如果大家有什么意见或者问题,欢迎回帖。谢谢!
Ps.,Visual Studio 2008中的MPI Debugger 插件已经发布了,欢迎大家从这里免费下载使用。Visual Studio 2010中的MPI Debugger将随Visual Studio 2010发布,敬请期待。
1993年我加入阿冈国家实验室数学和计算机科学部做Ian Foster 的博士后。
Ian 告诉我,现在科研经费的要求和实际实用应用相结合。为此,我们不能再搞什么logic / functional 语言了。必须和Fortran/C有关。 此时他发明了一个新的语言Fortran-M (M- 代表message passing)。 这个语言实在太像Occam了。Occam 里有Channel, Fortran-M 叫port. Occam的Channel 是强类型的,Fortran-M Port 也是强类型的。Occam 里有Process,Fortran也有,并且,Process可以动态产生!
Source:
我为这个语言写了编译器。Steve Tuecke (后来的globus 架构师)和Bob Olsen写了运行时系统。我倒是非常享受这个项目。那时的我,就是喜欢往系统栈的底层钻。当时的我,觉得世界上没有任何其他的研究比创建并行语言的编译和运行时系统更有吸引力。我当时觉得,并行计算的栈MPI 已经差不多完善了。而并行语言和运行时系统将是把并行计算推向主流的关键技术。
不过,一件事情改变了我的看法。
一次,我正在做MPI 和Fortran-M 的性能比较实验。结果Rusty Lusk来到我的办公室。满脸不悦。他说我在他的机器上运行了一个MPI 程序,使他的机器非常慢。问我是否可以杀掉它。我觉得很奇怪,我是用了他的机器跑了mpirun. 不过我已经Ctrl-C停掉了我的mpirun。怎么还会在他的机器上跑呢? 后来才知道,他写的MPIRUN是使用rsh 在远程机器上启动MPI 进程。Rsh可以将远程进程的stdout, stderr 转到客户端,使用户有个透明的感觉。但是,当用户键入Ctrl-C 的时候,只是把mpirun 进程杀掉,而远程的进程就逃匿了。 不光没有被杀掉,而且在背景里跑得非常欢。 结论是,Rusty是“自食其果”。
我搜索了网络,发现这种逃匿MPI进程(Runaway MPI Processes)是许多超级计算机中心中造成极大的破坏。用户总是抱怨,怎么超级计算机越用越慢!其实都是因为每次mpirun 非正常中断后,在远程节点就会有逃匿进程出现。管理员最头痛地就是要时不时地登陆到几十个甚至上百个节点上去清除这些逃匿进程。
后来当我加入Platform Computing时候,周松年问我能为MPI做什么?我就说我要解决逃匿进程问题。在1996年我花了半年写了一个Parallel Application Support Software. 能够完全解决逃匿进程,并且还能精确地采集计算资源使用数据。后来成为公司LSF Parallel产品。
今天您使用HPC服务器的MSMPI,您也不会发现逃匿进程。这就是投入生产使用的运行时系统和学术界软件的区别。 这点,我们必须归功于那次Rusty Lusk和我的小小的不愉快。这点小不愉快,让我开始关注到许多用户因受MPICH的启动方式而导致的逃匿进程之苦。
并行机在专有机时代分两大阵营,共享内存和分布式内存结构。
共享内存所提供的编程界面是非常优雅的。分布式内存机器的编程界面是基于消息传输库,不够优雅。串行程序的并行化相对容易的多,因为任何一个线程都可以访问到所有的数据,因此不需要对原来串行程序在结构上作大的改动。 而为分布式内存机器写程序却不同,首先应用域的数据就要分块,每个进程不光需要本地数据,还要边界数据。在本地计算完后,还要和邻进程交换数据。程序结构上要做大改动。
共享内存最大的缺陷是物理上的。是因为其扩展性差。当时80年代的处理机是很慢的了,可是到了32个就出现瓶颈。 这无法能够满足美国能源部许多宏大挑战性问题(Grand Challenge Problems)。所以当时分布式内存的拥护者流行的一句话就是:“Speed beats beauty”。
一个很自然生发的美好愿望就来了:能不能使用物理分布式内存,在其上建立共享内存的界面。 这样我们不是就取两者精华去两者之糟粕吗? 分布式共享内存(Distributed Shared Memory – DSM)这样的机器就成为了专有机时代最后一个大创举。
这个基因杂交出来的机器却有致命性的DNA缺陷。我一九九一年加入了曼彻斯特大学新奇计算中心 (CNC) (Centre for Novel Computing) 在John Gurd教授下作研究员。John Gurd 是数据流机器的知名学者。
我加入后不久,CNC就拿到一笔科研补助金(research grant) ,Gurd 教授在诸多的专有机厂商中挑选了一个Kendal了 Square Research (KSR)。其用意在于这个中心的名字里有个“新奇”。九十年代初的英国,爱丁堡和不利索托(Bristol)的中心里有不少大型专有机。绝大部分都是分布式内存。所以,Gurd教授觉得再买一个属于重复。正好KSR 是一个分布式共享内存的机器。这也就给了我一个和这个杂交机器零距离接触的机会。在这个机器上可以用标准的Pthread库,可以用锁来同步对于共享内存的访问。操作系统自动将不同线程分布到不同的节点上。而节点之间的操作系统实现了定制的多机内存的一致性协议。这样编程的确简单了。 机器及软件环境的细节大家可以参考维基百科:http://en.wikipedia.org/wiki/Kendall_Square_Research。 恕不赘复。
我当时对于这种新奇机器是充满热忱。在短短半年内,我移植了许多并行逻辑和功能性语言(Parallel Logic and Functional language) e.g. Strand, PCN 等。我之所以能够很快地移植这些语言,是因为共享内存不需要对程序结构有大的改动。
那么KSR致命DNA弱点在哪里呢?就是性能和扩展性差。为什么物理分布内存还会有性能和扩展性问题呢?
首先,它是在硬件和操作系统实现内存缓存一致性协议。为此它的RISC 芯片是专有定制的。这就意味着它无法和业界的豪门IBM, Sun, SGI, HP等RISC 芯片的性能匹敌。第二,也就是最关键的, 这点还是后来我加入Platform Computing后和公司的CEO周松年聊起后受的启发。周松年说:“DSM 在性能上无法和消息传输库并行化的比拟的原因是,DSM的管理单元是进程的地址空间的页(page),它无法反映应用对数据的访问情况(access pattern)。而消息传输库使程序员能够充分利用应用对数据访问的知识来优化并行算法数据访问的局部性(locality)“。 他的透视使我顿悟。缺乏对于应用访问数据的知识,就无法优化对于数据的访问的局部性。 分布式内存的机器造成了多层内存(本地和远程内存)状况,影响应用性能最大的因素,就是是否能够极大限度地访问本地内存。
自KSR 破产后,我再没有看见过一个DSM的机器。
(待续)
在专有机时代作并行计算的研究,你得会投“胎”。当时,全球科研的浪尖是在美国,能在Communications of ACM上发表论文的,都是美国大学的。用的HyperCube, Cray,Connection Machine 2 等大型机。而在英国,只有国产Transputer。 更可悲的是,我所在的埃德塞特大学(Exeter University), 我们当时只有四个transputer 节点。当时在英国,可以说是望着大西洋对岸的美国兴叹啊!我看美国人的论文的心情,就好比是一个穷人家的孩子偏偏喜欢上摄影,然后看着有钱人家的少爷拿着长焦、广角镜头,口水只能往里咽。
1993年,我到了美国阿冈(Argonne)国家实验室后,我就好像是小孩进了糖果店,因为那里有不少专有机(CM2, Paragon, Sequent等)。我问秘书预订了每个专有机的用户手册。每个手册都有电话簿那么厚,当秘书象我小时搬蜂窝煤一样把几英尺厚的手册搬进我的办公室后,她累得大抒一口气。现在看来,真是浪费了,这些手册我都没有用过。不是我没有用功,而是专有机被第一批微处理机颠覆了!
在80年代时候,多种消息传输环境被开发出来。有些是为专有机开发的Ncube. 而另外不少是为Unix工作站开发的。比较有名的是Oak Ridge 实验室的PVM (Parallel Virtual Machines) 和阿冈(Argonne) P4 和PICL, Ohio 超级计算机中心的LAM。
当我看到PVM 的时候,我也就不望洋兴叹了。因为用工作站组装成一个超级计算机,不用花大钱去买专有机。而且写程序也是用常见的C或Fortran语言。不需要专有的语言。 一下子,高性能计算的世界在我眼前变平了。
到了1992年末,听说又要搞个什么MPI。我和一帮英国同事都在笑,怎么又来一个消息传输库。后来才知道,我们笑得过快。原来,MPI是要吸百家之长、制定工业标准、省得大家重新发明轮子、浪费体力精力脑力人力。 Argonne和Oak Ridge 都是美国能源部的实验室。两个实验室,为了一个消息传输库争夺用户,结果使得能源部的应用开发成本提高两倍,这是实在说不过去。1994年这个标准终于出来了,不到两年的时间出来了这个标准,在HPC领域是相当快的。而且有许多学术界的人士参加的标准Forum, 一向是拖拖拉拉,没有目标导向,企图把海水烧开。为什么MPIForum 能够如此神速地推出此标准呢?
这要归功于两个人,Bill Gropp 和 Rusty Lusk, 他们都是从阿冈国家实验室的科学家。不要笑,他们的抬头就是“科学家”。
Bill Gropp Rusty Lusk
他们告诉我,最重要的原因,是MPI一开始就有一个参考实现:MPICH。 是他们两人主写的代码。所以,一旦有了一个可以参考的MPI库。一些应用就可以开始并行化。这样,许多没有任何应用场景的“好主意”,就很容易被扔到“Out of scope”栏目。帮助参加讨论者集中注意力。还有,他们采用的方法是一天早中晚连轴转的方式,如此高强度的讨论,只有那些铁杆、硬核的人才能挺得过去。所以,也把一些不懂行,不委身、但往往容易随机化讨论的人自然淘汰出局。
很多人把集群的概念归于Beauwolf. 其实,集群已经在九十年代初,就有了。许多人都以为,是beauwolf 集群后,工业界才开始使用。历史并非如此。听我给同学们表来。
在美国East Hartford,驻扎着著名飞机发动机厂商 Pratt Whitney的设计中心。过去,为了测验叶片的强度,他们要将一个冰冻鸡扔向高速旋转的发动机上,然后分析断面。 毫无疑问,造价极高。后来,他们使用Cray来做模拟仿真。只是能够模拟单叶片。而且Cray成为稀有资源,每个工程师的作业,都要排上两天才能算上题。
90年代上半叶,Pratt Whitney的CFD组,开始自主设计、开发一套消息传递系统,Prowess。它可以扩展到上千台太阳工作站。其中带头人名叫Craig Fischberg, 因此在制造业界成名。95年左右,GE 飞机发动机给了他双倍工资并为其妻子安排了很好的工作,把他挖了去。后来,他又用MPI 来为GE建立了同样系统。从此,他在GE 的地位如日中升。
一想起工作站资源觅食(Cycle Scavenging)人人都以为最早是由Seti@home. 其实,在九十年代初在Pratt Whitney 已经有了。
那么从Cray 到工作站集群到底带来什么大不了的效益,使得GE出血本要挖人才呢? 后来,Craig Fischberg 跟我讲,以前只能在叶片上模拟,后来能够把模拟整个发动机。以前的排队时间长至3天,结果晚上提交,第二天一早就可以看见结果。结果呢,高耗资的物理测试减少了,设计时间缩短了一半,而且飞机引擎的油耗效率大大提高。所以,GE能不受刺激吗?花了双倍工资挖到了Craig Fischberg是非常小的代价。
成百上千的工作站的计算能力被完全释放出来。他们用的作业调度器是Platform Computing 的LSF。 所以,在九十年代,LSF的用户手册写着“Unleashing the Power” – 释放能力!就是从这儿来的。
机器厂商
IBM,SGI, HP 和SUN
硬件
精简指令芯片
处理器间网络联接
定制化的网络
应用软件编程界面
MPI-工业标准 PVM 和其他 消息传递软件包
作业调度软件
LSF, PBS, Sun Grid Engine (SGE)
为什么会有那么多的定制化的网络联接呢?我们下次再说。
下次内容: 我和Rusty Lusk 的一个不开心遭遇引发我的奇想。