我相信HPC中使用了许多Fortran,但不确定是否仅是出于遗留原因。
现代编程语言的功能(例如垃圾回收或运行时多态性)不适用于HPC,因为速度很重要,因此不确定C#或Java或C ++的来源。
有什么想法吗?
我相信HPC中使用了许多Fortran,但不确定是否仅是出于遗留原因。
现代编程语言的功能(例如垃圾回收或运行时多态性)不适用于HPC,因为速度很重要,因此不确定C#或Java或C ++的来源。
有什么想法吗?
Answers:
在(1)遗留代码很少,以及(2)开发时间和代码质量很重要的领域,我已经看到许多用于HPC的Java。典型的应用领域是金融,数据挖掘或生物信息学。
它确实取决于应用程序(线性代数之外还有生命),但是最近的JVM的性能通常与C代码相当。当JVM能够在运行时执行静态优化程序(C,Fortran)无法执行的聪明优化时,有时会更快。当有大量的符号计算时,绝对更快。
在程序开发有固定时间的情况下,生成的Java代码始终比C代码更快。经常开发或修改代码时,Java中的HPC绝对有意义。另一个重要功能是不同硬件上的代码移动性。
您可以在http://ateji.blogspot.com/2010/09/java-for-high-performance-computing.html中找到参考。
关于Fortran假设两个地址是唯一的假设,我们正在开发一种静态分析工具,该工具将对高级语言中的代码进行类似的优化,但不会出现“可能发生的不良情况”。有兴趣请与我联系。
根据我的经验,直到5年前,一直都是Fortran和C。这主要取决于人们是来自工程学还是来自CS思想学校(我不知道如何更好地做到这一点) ,好吗?:-)
在我们所做的工作中,几乎只使用了Fortran。
从我今天读到的内容来看,随着对标准F2003 / 08的新更新以及Co-Arrays的推出,它似乎又开始获得动力。
另外,还有一篇,即使不是有点偏见的文章- 理想的HPC编程语言
我认为对于真正的踏板来说,唯一真正的选择是Fortran。推理是,利用低级ILP(指令级并行)最重要的是内存地址的歧义消除。Fortran中的实际规则允许编译器确定两个地址是唯一的(因此可以互换加载和存储的顺序,甚至可以互换存储和存储的顺序,而不会产生错误代码)。C为重叠的指针留下了太多的余地,使编译器无法从代码中提取尽可能低的并行度。
而且,阵列对齐,WRT缓存行和SSE / AVX边界对于有效循环的生成和执行也很重要。如果通过公共块传递数组,则编译器/加载器可以确保所有数组都在相同的地址对齐边界上开始,并且可以利用更有效的SSE / AVX加载和存储。较新的硬件可以处理未对齐的内存访问,但是由于内存访问未正确对齐,部分使用缓存行会导致性能降低。即使C程序员正确对齐了他所有的数组,是否有一种机制可以将其传达给编译器?
总而言之,两个最重要的问题是内存地址的独立性,以及编译器认识到所访问的数据结构具有与硬件所需的“自然”对齐方式。到目前为止,Fortran在这两项任务上做得最好。
只是一些轶事。我自己还没有进行任何高性能的计算。
对于计算(数字运算),Fortran和C。是的,这是出于遗留原因:
数字处理的当前趋势是编写程序生成器,以自动执行源代码调整,以在给定群集特征的情况下优化性能。这些生成器通常以C输出。
第二个趋势是为特定的GPU或Cell BE写一些专门的C语言。
对于非数字工作,例如处理来自数据库的数据(而不是数据库本身)的程序,在没有昂贵的定制网络设备的情况下在“商品”计算机集群上运行便宜得多。通常将其称为“高吞吐量计算”。Python是这里的第一语言(使用著名的Map Reduce)。在Python之前,批处理项目可以用任何语言编写,通常由Condor调度。
我一直在(gasp!)C#中处理一些非常需要计算的代码。
我正在为光学建模构建FDTD的GPGPU实现。在小型(128处理器)群集上,我们的许多模拟都需要数周的时间才能运行。但是,GPU实施的运行速度往往快约50倍-并且在消费级NVidia卡上。现在,我们有一台带有两个GTX295双处理器卡(数百个内核)的服务器,并且即将推出一些Tesla。
这与您的语言有何关系?以同样的方式,我们使用之前,C ++代码FDTD是CPU密集型的,这些都是GPU结合,所以(非常托管VS本地代码小)马力的差异不会永远发挥作用。C#应用程序充当指挥者-加载OpenCL内核,将数据传递到GPU或从GPU传递数据,提供用户界面,报告等-所有使C ++陷入困境的任务。
在过去的几年中,托管代码和非托管代码之间的性能差异足够大,以至于有时值得使用C ++的糟糕对象模型来获得额外的百分之几的速度。如今,C ++ vs C#的开发成本远远超过了大多数应用程序的收益。
同样,大多数性能差异不是来自您选择的语言,而是来自开发人员的技能。几周前,我从三重嵌套(3D数组遍历)循环的内部移动了一个除法运算,从而将给定计算域的执行时间减少了15%。这是处理器体系结构的结果:划分速度很慢,这是您只需要在某处拾取的一张面孔。
Fortran最常见,主要是由于遗留(人们仍在运行旧代码)和熟悉度(大多数执行HPC的人不熟悉其他类型的语言)。
现代编程语言的功能(例如垃圾回收或运行时多态性)不适用于HPC,因为速度很重要,因此不确定C#或Java或C ++的来源。
一般来说,这是不正确的。经典的HPC大多使用机器精度的数字进行线性代数运算。但是,现代HPC越来越多地使用超级计算机进行各种运算,例如使用具有任意数学表达式而不是机器精度数字的符号计算。这给您使用的工具带来了完全不同的特性,并且使用除Fortran以外的编程语言并不罕见,因为如果没有GC和其他类型的优化编译器(例如OCaml的优化模式匹配编译器),符号计算将非常困难。
例如,请阅读Fischbacher 等人的这篇论文。其中说:“作者有充分的理由相信这很可能是迄今为止进行的最大的符号计算”。
Fortran,出于某些良好和不太好的原因。对于繁重的数学运算,有一个很好的理由是,有大量经过实践检验的子例程库(BLAS,LAPACK),它们都是用Fortran编写的(尽管可以从C和C ++调用)。
一个不太好的原因是Fortran相对于C / C ++的性能优势。优化器非常好,很少有人知道优化一段代码的好处与繁忙时间的百分比成正比,几乎所有代码几乎都为零。
另一个不太好的原因是CS和非CS程序员之间的文化鸿沟。在Fortran中,往往会教给科学程序员一些坏习惯,而对CS程序员和他们所教的坏习惯则一视同仁,而谁则鄙视前者。
基本上,所有进行数字运算的程序仍然是FORTRAN(仍然使用旧的blas,lapack,arnoldi等)...但是,当涉及到更高层次的结构时,人们越来越多地使用C ++。
模拟的复杂性涉及大量代码,而从编写代码中获得任何好处,就是使其可重用。而且,所使用的概念也变得非常复杂。使用FORTRAN表示该信息几乎是疯狂的。这就是C ++出现的地方,因为它固有地支持面向对象的设计。但是,运行时多态很少被首选。人们几乎总是使用静态多态性(使用模板元编程在C ++中实现)
而且,现在的编译器确实非常好,因此需要对编译器进行很多优化。