作为FORTRAN老用户忍不住来撕一下。
FORTRAN就是用来把公式敲到程序中去的,像我们写的CFD代码,根本没有嵌套多层的函数,也没有什么复杂的程序结构,一个SUBROUTINE几千行,全是加减乘除的式子,要什么面向对象呢?
另外FORTRAN本身的编辑逻辑非常简单,数组就是数组,变量就是变量,从数组中取哪个数就是取哪个数,没什么指针移位什么的。全局的数组在SUBROUTINE或者FUNCTION之间传递非常直观,许多函数都去操作全局数组也不会出错。
编译器里的指令级的SIMD向量化是针对最底层的,所以我才不要什么外部的数学库,我需要我们自己写的DO循环是那个被向量化的最底层,许多FORTRAN程序员的习惯恰好满足了这一点。我们是不介意连FFT都自己写的,我们组的程序除了MPI以外没有使用任何外部的库,所以并行粒度到哪个层面就很清楚,可以AVX+openMP+MPI混用。并且作为算法研究,我需要知道计算中所发生的一切,依赖外部的库总是感觉心里没底。
很多人说的FORTRAN的矩阵操作很方便,在我们这里也是不存在的。CFD在某些阶段(甚至是很高的层面上)是需要求解线性方程组不假,但是这种超大的稀疏矩阵根本不是靠库函数直接求逆或者直接做矩阵向量乘法的,甚至根本没有存储过整个系数矩阵。每个元素具体的算法几乎全部是手敲进去,花上百行去实现一个格式算出一个系数,最后用一行乘掉拉倒,根本没有显式的矩阵运算。向量操作倒是偶尔用一下,省一个DO而已。所以很多人理解的所谓FORTRAN矩阵操作方便的优势,在我看来并不是主要原因。
有人说应该权衡一下,牺牲一点程序性能来节省编程的时间,我觉得说的很对,但在不同领域这个平衡点是不一样的。像我们CFD领域,有时在集群上等一个结果有时要数月,大家还都在排队,所以程序运行速度绝对是非常重要的。机时是很大的成本,你的程序效率太低,收益与成本不对称,可能连挂上去的机会都没有。商业领域也是一样的,计算服务器也是成本,跑得快的程序直接意味着真金白银的成本节省,这是那些“立等可取”的应用所无法想象的。
我的感觉就是敲式子并不难,式子本身是什么才更重要。FORTRAN程序员都不认为自己是程序员,而都说自己是搞计算的,懂的人自然知道“搞CFD的”和“用CFD做研究的”是完全不同的概念,前者更牛一些,大佬级的也多为前者。不需要把研究员逼成专业程序员,就能把算法实现得挺好挺快,我想这就是FORTRAN存在的价值。大佬们需要,这就够了。
当然,FORTRAN面向的用户也越来越窄了,因为计算机不再是尖端科学计算的专属,已经“飞入寻常百姓家”了。什么人都在编程,就一定会有程序员出来造反,“要革FORTRAN的命”,这也是正常的。事实上目前坚持在用FORTRAN的都是大几十年的传统学科(而且是超大规模计算的那种,比如各种流体计算,航空航天的、核爆的、气象的等等),看来来像是小众用户了,但是仍然是很有钱的少数。目前基本只有intel和NVIDIA(买了原来的PGI)两家硬件商还在做,因为高性能计算是他们的大客户,那些超级计算机上也是离不开FORTRAN的。
我也用CUDA,它也是直接针对高性能计算的,为我节省了很多的计算成本(自己独占GPU机器不用排队爽歪歪),但是用CUDA做CFD真的非常小众,需要适应的过程,也经历了被神话和被质疑的过程。FORTRAN的定位某种程度上讲也是类似的。试想你用C++鄙视CUDA,认为CUDA应该消失,有意思么?
“FORTRAN灭亡论”可以休矣。
其实这是个很私人的问题,完全看你自己需要不需要了。小明手头有一个发展了十年,十几万行的fortran程序。心里琢磨看是不是需要推倒重来呢?小明实在是对fortran看不上眼,决定开启一段伟大的旅程:发展一个全新的C++程序,估计最终规模有十几万行。看看是不是需要把什么oo,design pattern,xml,boost,python封装,traits都用上,规划几十个namespace,几百上千个类,继承个五六七八层……?是不是显得很有big?
鄙视FORTRAN和推崇C++的人往往喜欢把OO挂在嘴上。但是把复杂系统OO化看来是过于理想主义了。犹如“过早优化是sb”一样,“过早设计也是sb”。但是不断的迭代OO设计会陷入不断的建模-重构-重构-重构,最后疯掉或者从屎山中挣脱出来。复杂的OO设计和goto泛滥同样都是灾难。后来者面对堆积如山的class和复杂的耦合关系,迟早会彻底失去探索的勇气,然后只会流于表层。最后,我们会发现“我TNND把精力都耗费在设计上了,成天折腾这些类之间应该怎么耦合关联交互,而没有精力去研究算法、提高性能和思考物理问题”。
补充:
其实,我并非是死硬fortran用户。我的意思只是说fortran有它自己的用武之地,C++和现代动态语言的fans们没必要狂喷fortran。我其实同时使用fortran与C/C++。不要迷信OO,更不要过度的OO。OO只是一种设计哲学。可是软件设计并非只需要一种哲学。复杂系统OO化是很难的,当你把它分解为许多比较单纯的子系统之后,你会发现某些单纯子系统可能没必要OO。
相反,经过好几年的折腾,我自己发现,在数值计算中,数据和操作分离的设计(有点像函数式编程咯)是值得关注的。
(撇脚的)面向对象设计者往往会:
尽管可以通过精心的分析与设计来避免或者减轻这些问题。但是这纯粹是没事找事。为什么不按照数学公式原有的模样来写呢?这样不就没有这些问题了?比如函数,就编写为
void fun(double* rho, double* u, double* v, double* w, double* sx, double* sy, double* sz, double* vol, double* mu, double* mut, (double *) outRes[5]);
它只是根据参数计算出结果outRes,不会对outRes之外的任何变量进行修改,也不管这些参数从哪里来。很显然,在函数参数较多的情况下,这个做法被很多C++的fans所嫌弃。但是这种方式的价值就在于,它单纯的表现了函数的输入与输出关系,没有不必要的绑定,没有状态记忆,没有高阶对象(只有基本的数组)。
一旦按照这样老土方式设计,函数的重用就简单了。很多基础数学库,就采用了很老土的设计。我琢磨设计者也考虑到在底层不能引入太多的复杂概念,抬高上层应用开发不必要的成本。
但是在更上层,对于合适的情况,可以考虑其它设计思维。
所以,我说的是,设计方式要因地制宜,抱着一种思维不放,那是自找麻烦。迷信OO放之四海而皆准,那是痴人说梦。
fortran现在还在继续被人大量使用最主要还是历史遗留问题。作为最早的高级语言,现在市面上存在大量的的遗留代码。那些代码可是久经考验基本上没啥问题可以直接就拿来使用的。
而且现在主要是学术界在使用fortran。学术界的特点是以一个个实验室为最小单位,铁打的营盘流水的兵。一个学生基本上干个几年就毕业了,面对动辄上百万行的代码,自己也就干个几年,真心犯不着用其他语言重新写。
再加上在学术界重要的不是你用什么语言写,而是你的算法是什么,证明这个方法能用就行了。这导致目前有大量的教授级的人没有任何的动力去学新的语言。现在还有一大票人用fortran 77在发论文。
本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度,google,bing,sogou 等
© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有