技术开发 频道

Visual Studio 2010中调试并行应用程序

  【IT168 技术】未来属于多核技术时代已经得到了CPU或GPU硬件厂商的共识。因此怎样通过并行性来发挥多核的优势便提上了议程。在Visual Studio 2010中,微软引入了众多的新库和运行时,以此来简化基本代码表达并行性的过程,并且支持新工具对并行应用程序进行性能分析和调试。

  从实际应用出发

  并行性融入应用程序是为了利用多个内核,以前单一的顺序工作一次仅在一个内核上运行。 要使应用程序使用多个内核,需要让多项工作启用多个线程,以便对该工作进行并行处理。 这样,假如只有一项工作,那么要想通过多核执行实现并行加速,就需要将该单一工作划分为可并发运行的多个单元。

  最简单的方案是静态划分: 将工作划分为固定数目、固定大小的单元。但是,这种方法仍然差强人意。 在实际环境中划分工作负荷时,很少能够保证每个单元都占用同样的处理时间,尤其在您将一些外部因素(如可能在计算机上同时运行并消耗部分计算机资源的其他工作负荷)考虑在内时。 在这种情况下,每个内核一个单元的划分最终可能会造成不均匀的工作分配: 某些线程将先于其他线程完成其单元的处理,从而造成负荷不平衡,而某些内核在其他内核完成时处于空闲状态。 为解决这一问题,您需要对工作进行深度划分,将工作负荷划分为可行的最小单元,以便计算机的所有资源都能参与工作负荷的处理,直到处理完成。

  如果执行一个工作单元引起零开销,则刚刚提出的解决方法将较为理想,但很少有实际环境中的操作会引起零开销。 根据过去的经验,线程一直是用于执行这样一个工作单元的机制: 为每个工作单元创建一个线程,让其执行,然后终止该线程。 遗憾的是,线程相对来说是重型的,以这种方式使用它们所产生的开销可能会禁止我们所讲的深度划分类型。 您所需要的是一种用于执行这些已划分的单元以将开销降到最低程度的更轻型机制 — 一种可使您更放心地进行深度划分的机制。 通过这种方法,您不是为每个单元创建一个线程,而是利用一个计划程序来计划在它所管理的线程上执行的各个单元,从而在保持单元数目尽可能少的同时仍能确保实现最大吞吐量。

  刚刚介绍的是一个线程池,它将线程管理成本在计划给它的所有工作项中分摊,从而将与单个工作项关联的开销降到最低。 在 Windows 中,可通过从 Kernel32.dll 导出的 QueueUserWorkItem 函数访问这种线程池。 (Windows Vista 还引入了新的线程池功能。) 在 .NET Framework 4 中,可通过 System.Threading.ThreadPool 类访问这种线程池。

        调试

  虽然Visual Studio 2005有一个内建的MPI程序的简单调试器,但并未提供完整的“F5”体验。在新的Visual Studio 2008 插件(同时也将集成到Visual Studio 2010中)中,您只需选择一个集群头节点以及您需要多少核,然后按F5就可以对您的MPI程序进行调试了。

图1 调试MPI

        除了调试团队所作的很棒的核心工作以外,并行调试技术的领先供应商Allinea还将他们的环境导入到了Visual Studio中。Allinea的插件提供了针对集成的MPI程序的调试,包括基于排名的上下文切换、组单步调试、暂停及运行、并行栈视图和迭合。下面是Allinea的MPI调试环境:

图2 Allinea的MPI调试环境
        面向服务的架构调试

  Windows HPC Server 2008的一个重要的新的编程模型是集群系统面向服务体系架构 (Cluster SOA),它是基于WCF构建的,并包含由HPC的调度器和代理节点提供的高级调度和负载平衡功能。目前为止,对面向服务架构的集群系统的调试还仅仅限于基本的WCF/.Net方式的调试,并无集群的集成。在Visual Studio 2010中,一个集群面向服务架构插件将提供SOA设置标签,在这里您可以选择头节点、调试节点和服务、部署运行时类库并自动进行清理。现在来看一下Visual Studio 2010中新的SOA调试器吧:

图3 SOA调试器

  剖析 (Profiling)

  Windows Server HPC 1.0中没有集成针对MPI程序的剖析功能。在Windows HPC Server 2008中,XPerf等工具提供了MPI的剖析以及系统级别的剖析和故障排查的功能。但即使是XPerf也对MPI消息流量等细节所知甚少,目前为止也没有消息流量的浏览器。自那以后,消息流量浏览器Vampir被导入到Windows并完整地集成在事件跟踪日志(ETW)中。Vampir提供了对消息顺序和延迟进行故障排查的功能。还有更多的开源HPC工具,比如JumpShot是一个免费的基于Java的MPI消息浏览器。

  在很多时候,VS内置的剖析器就能提供性能问题的分析。在Visual Studio 2010中,这一功能与HPC工作调度器进行了完整的集成,用来分析一个特定的MPI排名或节点的性能。Visual Studio MPI 剖析功能提供了行级别的剖析信息,包括与源代码视图并排的执行过程中的温度视图:

图4 源代码视图并排的执行过程中的温度视图

  剖析器还显示多个运行或版本的结果比较报告,这样您就可以轻松地了解您的修改所带来的效果。

图5 多版本结果比较

  MPI 运行时分析

  除了调试器和剖析器之外,有时您还需要专门的分析工具来帮助分析大规模并行程序的复杂度。位于斯图加特的HLRS/ZIH是德国的一个在该领域领先的机构,将他们自己的MPI分析工具Marmot导入到了Visual Studio 2008。Marmot可以用来检查MPI调用的输入参数的合法性、检测无法再生性、死锁和对资源的不正确管理。下面是运行中的Marmot:

图6 Marmot运行中

  从Printf到集成的剖析和调试

  不久前我们还在printf风格的调试世界里,“艺术级”的调试和剖析工具将此往前推进了一大步。

  在Visual Studio里,您可以调试和剖析高性能MPI程序以及拥有成百到上千个核的集群SOA应用程序。您可以使用XPerf和事件跟踪日志来获取应用程序在整个系统环境中的全局视图。Visual Studio 2010里新增的多核剖析和调试工具也可以有效地用于集群的节点级别分析。

  Visual Studio正成为越来越丰富和有效的编写各种并行程序的开发环境。访问Windows HPC Server 开发人员资源中心您能找到更多关于Windows HPC的开发模型。在CodePlex的Parallel Dwarfs站点上您能找到许多使用各种Visual Studio 2010并行编程模型的示例。

0
相关文章