|
很多计算机专业的工程师可能很难理解为什么会有几十年历史的“祖传代码”,实际上,这在工业软件领域是很正常的现象。以我所在的电力系统行业为例,很多祖传的Fortran是20世纪80年代后半段编写的,当时国家花了宝贵的外汇从美国进口了四套能量管理系统,后来很多团队国产化、自主研发,都在这四套系统上进行,当时(至少在电网分析仿真这块)用的都是Fortran代码。电科院的BPA也是在同一时期引进的。我记得几年前,自己还调试过Fortran程序,那些程序是1988年左右编写的,程序修改名单中记录着大佬的姓名。
对待这些Fortran代码,我唯一的建议就是:首先把Fortran代码改写成C/C++,然后在条件许可的情况下进行重构,至少要变得模块化、可维护。
有种流传已久的说法:在数值计算领域,Fortran比C/C++的性能要高。这是许多人不愿意放弃Fortran的理由。但我怀疑,在有现代编译器技术的今天,这种说法不成立了。
C/C++编译器处理指针时,必须考虑别名问题,就是指针所指向的内存区域可能会有别的指针来修改。而Fortran不存在这样的问题。为了提高效率,C语言可以用restrict 关键字来定义指针变量,表明该变量没有别名。C++标准没有restrict关键字,但是编译器都支持这种处理,比如gcc支持__restrict__。C++标准库中的valarray,据说是支持数值计算的容器。但是你如果读valarray的代码,会发现实在乏善可陈,没用到什么值得一提的优化技术,唯一用到的就是__restrict__。所以一般的建议是不要使用valarray,可以考虑高性能的矩阵计算库如Eigen。
我自己对restrict关键字进行了很多测试,实在是看不出restrict对性能会有所提高。我不是编译器专家,也没精力一行行读汇编代码,我怀疑:在现代编译器技术下,restrict关键字的意义已经不大了。连带影响就是:不能认为Fortran程序在数值计算方面优于C/C++。就算restrict的作用很显著,我们在编写C/C++指针时加上不就行了?
还有个佐证:在高性能的矩阵库(BLAS)实现方面,OpenBLAS用的是C语言和汇编语言,只是提供了Fortran接口而已。在稀疏矩阵方面,SuiteSparse用的是C语言(少数功能用的是C++)。
除了高性能数值计算,Fortran剩下的就都是缺点了。如果你阅读祖传的Fortran代码,会发现数千个全局变量,goto满天飞。至于封装、面向对象、泛型等等现代编程范式,那更是没有的。(虽然Fortran最新版本增加了对面向对象的支持,但据说用起来很多问题)。
把Fortran改写成C/C++只是第一步,因此架构上仍然是面向过程,goto也很多。可以在此基础上进一步封装或重构,然后就可以轻装上阵,后面的维护成本、增加新功能的成本都会下降很多。
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-12-7 06:20
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社