如果我希望将来的代码在petascale机器上运行,我应该投资哪种编程范例?


36

从对Top500的调查中可以很明显地看出,该行业正朝着处理核心呈指数增长的趋势发展。最大的超级计算机都使用MPI进行节点之间的通信,尽管似乎没有明显的节点上并行性趋势,并且使用最简单(但不一定是最有效)的方法将单个MPI进程映射到每个核心,自动来自编译器,OpenMP,pthreads,CUDA,Cilk和OpenCL的并行化。

我是维护和开发有潜力在世界上一些最大的超级计算机上使用的代码的一组科学家之一。假设开发人员时间有限,那么我该如何适应未来的发展,以便可以利用世界上功能最强大的计算机的性能?我应该对流程互连体系结构做出哪些假设?当我们进入众核时代时,将遭受哪些范式?在Petascale机器上是否可以在生产中使用分区的全球地址空间语言?


5
我认为这个问题范围不大。从常见问题开始,“您的问题应该合理地界定范围。如果您能想象一整本书都能回答您的问题,那么您的要求就太多了。” 实际上,我去过的每一次SuperComputing会议都包含有关该主题的多个小组,并且有数十到数百本专门讨论不同编程范例的书
aterrel 2011年


5
水晶球不可用,茶叶坠毁。
–'dmckee

Answers:


34

历史的角度

真的不可能说出新范式的未来,例如,我建议阅读Ken Kennedy的HPF兴衰的良好历史观点。肯尼迪介绍了两种新兴模式,即MPI与智能编译器,并详细说明了MPI如何具有适量的早期采用者和灵活性来主导市场。HPF最终解决了问题,但为时已晚。

在许多方面,PGAS和OpenMP等几种范例都遵循相同的HPF趋势。早期的代码不够灵活,无法很好地使用,并且在桌面上留下了很多性能。但是,不必编写并行算法的每个细节的承诺是一个诱人的目标。因此,始终追求新模型。


明确的硬件趋势

现在,MPI的成功通常被认为与其在其上运行的硬件的建模方式密切相关。大约每个节点都有几个进程,并且可以在集群空间中轻松地将消息传递到本地点对点或通过协调的集体操作。因此,我不相信任何提供的范例与新硬件趋势不紧密相关的人,Vivak Sarakar的工作实际上使我相信了这种观点。

与之保持一致的是,三种趋势显然正在新架构中取得进展。让我清楚一点,HPC 现在正在销售十二种不同的体系结构。这是从不到5年前仅具有x86的功能开始的,因此在未来的日子里,将会看到很多以不同且有趣的方式使用硬件的机会

  • 专用芯片:考虑大型矢量单元,例如加速器(视图由Nvidia的Bill Dally支持)
  • 低功耗芯片:基于ARM的群集(以适应功耗预算)
  • 筹码平铺:考虑不同规格的筹码平铺(Avant Argwal的工作)

当前型号

当前模型实际上是3个层次的深度。尽管有很多代码很好地使用了其中两个级别,但使用这三个级别的代码却很少。我相信,首先要进行万亿扩展,就需要投资确定代码是否可以在所有三个级别上运行。这可能是迭代当前趋势的最安全途径。

让我迭代模型,并根据预测的新硬件视图对它们进行更改。

分散式

分布式级别的播放器主要属于MPI和PGAS语言。目前,MPI无疑是赢家,但是UPAS和Chapel等PGAS语言正在进入这一领域。HPC基准测试挑战就是一个很好的指示。PGAS语言为基准提供了非常优雅的实现。

这里最有趣的一点是,尽管此模型当前仅在节点级别起作用,但它将成为Tiled架构的节点内部的重要模型。一个迹象就是英特尔SCC芯片,该芯片从根本上起着分布式系统的作用。SCC团队创建了自己的MPI实施,许多团队成功地将社区库移植到此体系结构。

但是说实话,PGAS确实有一个涉足这一领域的好故事。您真的要对MPI节点间进行编程,然后必须对节点内部做同样的技巧吗?这些平铺体系结构的一个重要问题是它们在芯片上将具有不同的时钟速度,并且在内存带宽方面存在重大差异,因此性能代码必须考虑到这一点。

节点共享内存

在这里,我们看到MPI通常“足够好”,但是仍然经常使用PThreads(以及从PThread派生的库,例如Intel Parallel Building Blocks)和OpenMP。普遍的看法是,有时共享内存线程的数量会过多,MPI的套接字模型将因RPC而崩溃,或者您需要在内核上运行更轻量的进程。您已经可以看到IBM Bluegene系统共享内存MPI有问题的迹象。

正如Matt所言,计算密集型代码的最大性能提升是串行代码的矢量化。尽管许多人认为在加速器中是正确的,但对于节点计算机也同样至关重要。我相信Westmere拥有4个宽的FPU,因此如果不进行矢量化处理,则只能获得四分之一的触发器。

虽然我看不到当前的OpenMP能够很好地进入这个领域,但低功耗或切片芯片仍有地方使用更多的轻线程。OpenMP难以描述数据流的工作方式,并且随着使用更多线程,我只看到这种趋势变得更加夸张,仅查看一些示例以了解如何正确使用OpenMP进行预取。

在足够高的水平上,OpenMP和PThreads都可以利用必要的矢量化来获得很高的峰值百分比,但是这样做需要以自然的矢量化方式分解算法。

协处理器

最终,协处理器(GPU,MIC,单元加速器)的出现受到了欢迎。越来越清楚的是,没有它们,万亿万亿美元的道路将是不完整的。在SC11上,每位贝尔奖参赛者都非常有效地使用了它们,以达到低petaflops。尽管CUDA和OpenCL主导了当前市场,但我希望OpenACC和PGAS编译器进入这一领域。

现在,要达到万亿级,一个建议是将低功耗芯片耦合到许多协处理器。这将很好地消除当前堆栈的中间层,并使用代码来管理主芯片上的决策问题并将工作移交给协处理器。这意味着,要使代码有效运行,人们必须从内核(或小码)的角度重新思考算法,即无分支指令级并行代码段。据我所知,这种发展的解决方案是相当广泛的。


这如何影响应用程序开发人员

现在开始回答您的问题。如果您想保护自己免受万亿级计算机的复杂挑战,您应该做一些事情:

  • 开发算法,使其至少适合三个层次的并行层次结构。
  • 根据可以在层次结构之间移动的内核来设计算法。
  • 放宽对任何顺序过程的需求,所有这些效果都将异步发生,因为同步执行是不可能的。

如果您想今天表现出色,MPI + CUDA / OpenCL足够好,但是UPC可以到达那里,所以花几天时间学习它并不是一个坏主意。OpenMP可以帮助您入门,但是一旦需要重构代码,就会导致问题。PThreads要求完全按照其样式重写代码。这使MPI + CUDA / OpenCL成为当前的最佳模型。


这里没有讨论什么

尽管所有这些关于百亿亿美元的讨论都很好,但是这里没有真正讨论的事情是将数据传入和传出机器。尽管内存系统取得了许多进步,但我们在商品集群中看不到它们(太昂贵了)。现在,数据密集型计算已成为所有超级计算会议的一大焦点,势必将有更大的步伐进入高存储带宽空间。

这带来了另一种可能发生的趋势(如果合适的融资机构参与进来)。对于所需的计算类型,机器将变得越来越专业。我们已经看到NSF资助了“数据密集型”机器,但是这些机器与2019年Exascale Grand Challenge的发展方向不同。

这变得比预期的更长,请在注释中索取您需要的参考文献


2
很好,但是如何忽略向量化,这是节点性能的最大因素?
Matt Knepley 2011年

非常正确(我实际上将其视为特殊计算节点的一部分,刚刚与带宽博士讨论了供应商实际上如何建议人们关闭串行代码的矢量单元),我也忽略了内存系统, / o。猜猜我现在将添加。
aterrel 2011年

Fortran中的协同数组是否大致等同于UPC?
昂德里杰·塞蒂克

据我所知,它们是相同的概念,但是我没有广泛使用这两个库。
aterrel 2012年

就CAF和UPC都是PGAS而言,是的。而且图书馆也不是,顺便说一句。互联网上有很多信息可以更详细地回答这个问题。
杰夫

8

让我们开始讨论节点内代码的策略(不涉及互连的计算),因为我认为MPI是节点间代码的不错选择。我认为谈论少于100个内核的节点是毫无意义的,因此至少要讨论当前的GPU或MIC。

这是一个事实,仅pthread不能在任何现代芯片上为您提供最佳性能,因为您必须利用向量单位(自第一个Cray开始为真)。在Intel和AMD上,您可以使用内在函数,但是内在函数不是可移植的,而且我认为它们很笨拙。CUDA和OpenCL在库中内置了矢量化功能,可以轻松获得最佳性能。我知道所有新硬件都具有此向量要求,因此任何解决方案都应考虑到这一点。对我而言,CUDA / OpenCL是当前的发展之路。

接下来,所有这些机器都是NUMA,很难编程,但是我认为内核策略可以工作。您将工作和数据分成小单元。这些可能会自动进行调度,就像当前在CUDA和OpenCL中那样,但是您可以指定依赖项。对于适合流式范式的问题,此分块也可以自动完成。英特尔TBB可以做到这一点,但我更喜欢ThrustCusp举例说明的高级库方法,该方法可以针对CUDA或(很快)TBB。


我还认为CUDA / OpenCL的方法有光明的前景...但是CUDA还是OpenCL会占优势?最近的AMD惨败会危害OpenCL吗?
PhDP 2011年

2
最终将有一个所有人都可以使用的开放标准。可能是OpenCL 2.0。目前,CUDA有点领先,但是我可以轻松转换95%的代码。
Matt Knepley 2011年

7

在这个主题上,我尝试的答案比一些尊敬的同事要短;-)

我向所有学生传达的信息始终是,开发人员时间比CPU时间更有价值。这意味着,如果您有时间使用高级方法在80%的效率下将100%的代码转换为在大型计算机上运行,​​那么与使用费时的低级代码相比,您的状况会更好一种方法,可在20%的代码上实现100%的效率。因此,我非常喜欢高级库。在该领域,我最喜欢的是线程构建模块(TBB),因为它使我能够从最外层的循环和更高层次上研究算法。它也可以完成您可能要使用pthread进行的所有操作,而不必处理操作系统功能等问题。我不喜欢查看最内层循环的方法,因为这是利用节点内并行资源的错误级别- -因此没有OpenMP,

我不能授权谈论OpenCL,CUDA等。


4

先前发布的答案非常好,但主要集中在节点体系结构上,我认为这反映了这样一个事实,即在大多数情况下,MPI通常被视为足以胜任节点间编程模型而这正是我们苦苦挣扎的节点内并行性。

这是我尝试回答两个尚未相对解决的问题或以相对有限的方式回答的问题:

我应该对流程互连体系结构做出哪些假设?

我将考虑网络的三个属性:

  1. 潜伏,
  2. 带宽,以及
  3. 并发。

延迟与频率成反比。我们知道频率缩放停滞了。因此,可以得出结论,等待时间将来不太可能显着减少。Blue Gene / Q上的MPI发送-接收延迟大约为2 us,相当于3200个周期。该延迟中有一半以上是软件,但MPI标准却需要很大一部分。广泛的调整可能会将延迟降低到接近1 us,特别是如果可以断言将不使用MPI通配符的话。

无论如何,Blue Gene和Cray系统上的数据包注入的硬件延迟约为1 us。如果有的话,增加节点级别的并发性将很难将其保持在如此低的水平,但是我乐观地认为,硬件设计人员将在可预见的将来找到将延迟保持在5 us以下的方法。

通过增加网络链接数,网络带宽会显着增加。但是,这只是故事的一部分。如果处理器无法以全带宽驱动网络,则可以在节点上放置1000个出站链接,并且不能使用它们。例如,就注入带宽而言,某些超级计算机是总线(例如HyperTransport)而不是网络的瓶颈。

网络带宽没有基本限制,只有实际限制。带宽会花费金钱和精力。系统设计师在开发未来系统时必须考虑网络带宽与机器其他部分之间的权衡。许多代码不受网络带宽的限制,因此将来似乎不太可能看到每连接带宽大大增加的计算机。但是,每个节点的带宽应与计算能力成比例地增加,因此每个节点需要多个连接才能扩展。

在形式化模型中经常被忽略的网络的第三个属性是一次可以发送多少条消息。对于大多数用途而言,拥有1 ns的延迟和/或1 TB / s的带宽的网络一次只能发送1条消息完全是没有用的。能够同时从多个线程发送大量消息,并且网络在竞争中不会崩溃,这一点很重要。Cray和Blue Gene系统现在都达到了1 MMPS(每秒百万条消息)以上。我不记得确切的数字,但是两者都能通过小消息实现很大一部分峰值带宽。理想的网络可能能够利用任何大小的消息都达到峰值带宽,但是由于包头和相关的簿记开销,在实践中这是不可能的。然而,

这是一个不完整和不完善的答案。欢迎其他人尝试改进它或提出我应该改进的地方。

在Petascale机器上是否可以在生产中使用分区的全球地址空间语言?

Cray XE,XK和XC系统具有生产质量的UPC和CAF编译器。Blue Gene系统可以与XLUPC和XLCAF一起交付,但是没有人要求这样做,因此没有交付。PERCS具有生产级的XLUPC和XLCAF编译器,但没有可供科学界使用的大规模安装。

协同阵列是Fortran 2008的一部分,尽管Intel和GNU Fortran中的实现还不是高质量的。据说Intel的实现工作正常,但速度也很慢(PGAS12上有一篇有关它的论文)。

至于PGAS编程模型(因为编程模型而不是编程语言是原始问题的主题),在许多情况下,全局数组库可以合理地近似于生产质量。作为运行时,它不如MPI健壮,但是MPI在实现质量方面非常独特。ARMCI的ARMCI-MPI实现使全局阵列更加稳定,尽管在某些情况下速度较慢。

使用MPI-3 RMA以生产质量的方式实现PGAS样式的构造相对容易。如果有人对此发表新问题,我很乐意回答。


4
您可以自己发布问题(并自己回答),以在MPI-3中实现PGAS样式的构造,只要这是您过去遇到的实际问题(我想是的)即可。我们允许用户回答自己的帖子。
Geoff Oxberry

1
这是最流行的scicomp问题之一,我很高兴在这里提出Jeff的答案。编辑:我明白你的意思了@GeoffOxberry-是的,他应该发表自己的问题并回答:)
Aron Ahmadia

好的,我会花一些时间在下两周内写一些硬核“ PGAS和MPI-3 RMA之间的联系是什么”问答。
杰夫,

3

确实有大量的内核也提供了琐碎但令人惊讶的有用视角-只是为了使用它来运行整个模拟的许多迭代。

如今,计算研究的重要部分归结为扫描某些参数空间,筛选大量初始条件或以重采样的方式计算某些结果的分布。所有这些任务都令人尴尬地并行进行,因此可以抵御Amdahl的麻烦。


2

我怀疑即使是最深思熟虑的答案在五到十年后也会过时。鉴于未来编程范例的不确定性,可能不值得花费大量时间对代码库进行预优化。


1
这太致命了-未来就在今天。问题是关于petascale,这就是我们今天所处的位置。如果您不考虑如何在当今的100,000个处理器上运行,那么明天的100,000,000个内核将不会有太大的进步。
Wolfgang Bangerth,2012年

1

我正要发布此问题的答案,但由于此问题的重复而被关闭,所以这里是:

这听起来可能有点“所罗门”,但根据我的经验,未来属于混合方法,其中多个运行多线程内核的共享内存多核节点通过诸如MPI的分布式内存范例进行连接。

但是,存在一些问题,它们根本不涉及硬件。首先,大多数并行程序员在MPI类型的代码上投入了大量资金,并且非常不愿意成为第一个使用新范式重新实现部分或全部代码库的人。缺乏使用共享内存方法的人会导致该领域算法的进展缓慢,这使得任何投资似乎都变得毫无意义。

第二个问题是每个人都将共享内存并行性与OpenMP相关联。尽管OpenMP是解决少量处理器上小的简单问题的一种好方法,但它却是真正共享内存并行性的绝对糟糕的编程模型。尽管我们都在某种程度上学到了许多简单有效的并行编程范例,例如线程池调度程序,但是使用OpenMP很难实现这些范例,坦率地说,这不是那种并行性。 OpenMP吸引了程序员的使用。

综上所述,从纯分布式内存向纯/部分共享内存的范式转变的障碍非常高。如果要高效地使用线程,则必须忘记OpenMP并自己管理线程和并发(您好pthreads,再见了Fortran)。

但是,为什么要完全采用混合方法呢?好吧,尽管MPI可以扩展到成千上万的内核,但是基础模型是锁步同步和静态通信模式之一。这对于某些问题(例如十亿个粒子的模拟)是有益的,但对于更困难或更细粒度的问题却不是最优的。共享内存范例使动态负载平衡和/或异步通信更加容易,但是这样做需要大量的编程工作。


1
我同意OpenMP是一个可怕的范例,正在给社区带来很大的损害。但是,与此同时,并非另一种选择是由您自己管理线程,线程池,工作队列等,这是不正确的—实际上,有非常好的库可以为您做到这一点。英特尔的线程构建模块最为显着。我们在Deal.II中已经使用了很多年,而且效果很好。
Wolfgang Bangerth,2012年

嗯,我一直在寻找使用TBB的强大应用程序或库,以验证我们的BG实施是否有效。我以前只找到cise.ufl.edu/research/sparse/SPQR。是否有任何机会,你会尝试使用BGP或BGQ运行deal.II wiki.alcf.anl.gov/parts/index.php/BlueTBB如果我提供的配置吗?
杰夫,

@WolfgangBangerth:只是引发了您的注意,因为我相信这就是Jeff的评论的目的。尽管我自己也不介意使用BlueGene;)
Pedro

@Jeff:我愿意尝试一下,但可能无法分配大量的时间。随时离线与我联系。(@Pedro:感谢大家的注意!)
Wolfgang Bangerth,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.