1 功能
c++什么都能做,早期fortran只能做数值计算,现在能做非数值的东西,但还是远没有
c++完备;
其实,fortran77是个好东西:专项、简单;从fortran90开始,哲学出了问题;
2 软件开发
c++是开发软件的最好语言,很大程度是因为它的“面向对象”的特点,其实就是“鼓
励”、“帮助”庞大的程序群的“创造”、“管理”;
用fortran写软件,不仅仅有些功能(如,对计算机软硬件的操作)没法办,而且整个
软件会被管理得一塌糊涂;用c++,10个人1年就能搞定的东西,if用frotran,同样10
个人估计需要5年;
3 软件工程
即便不是做软件,而是写个1万行数量级的程序,c++也因为promotes优良的编程习惯而
战胜fortran;
4 super c
如果没有那么多的“object”,不需要++,那么可以不用c++的那些oop东西,把它当作
一个改进的c,有人称之super c,来用;这样,c++和fortran都是command oriented的
结构化语言; 用super c 写的程序,将来能比较迅速地upgrade成软件,if fortran,
得重写;
5 交流
目前,计算机99%以上是用来“数据搬运”的,主要分“通信”、“数据处理”2大块
;比如,操作系统,就是一个数据搬运问题;
计算机1%不到是用来“数据产生”的,既科学计算;搬运工们基本不用real number;
科学计算的,基本用real number;
那些数据搬运工,即computer science人士,基本不懂fortran;
所以,做科学计算的,if用fortran,数据搬运工们的成果就不能及时拿来主义了;
6 关于“速度”的思辨
c++比fortran才慢10%左右;不用++的c++,比fortran慢得更少;
思辨一下:is 10% speed reduction A big deal?
a 你的程序快10%左右,这样本来需要24小时算完的东西,你的fortran程序22小时就
能算完;这很牛吗?
b 当计算机在计算的时候,你不可以去干别的事吗?慢10%妨碍你啦?
c 为了让计算机省2个小时,你愿意自己多花几百小时、甚至几千小时(this is the
case if 做软件)写程序、改程序、调试程序、维护程序,这样做,是不是太傻B了?
抑或傻A?
藕的博士论文程序只用了4个左右的很简短的subroutine,就完成了“并行计算”,效
果是:8个processors,速度是8倍;
以下是其中一个subroutine:
// filtered gathering of condensed local vector, make sure incoming data not modified
#include "globalDefined.h"
#include
#include
using namespace std;
#if parallel
#include "mpi.h"
#endif
extern int MPI_Rank, MPI_Size;
extern int MPI_SendList[MPI_MAXSIZE], MPI_ReceiveList[MPI_MAXSIZE];
extern int MPI_Inf[2], MPI_Inf_Buffer[2];
extern double MPI_Vector[MPI_MAXNUMROW], MPI_Vector_Buffer[MPI_MAXNUMROW];
void MPI_superpositionFiltered (
int localContribution, // 0 or 1: local contribution included or not
int rowCounter, int rowToNode[], int nodeToRow[], double vector_local[],
int counterFilteredList[],
int rowToNodeFilteredList[][MPI_MAXSIZE], // indexed by outcoming data
double vector[]
)
{
#if parallel
MPI::COMM_WORLD.Barrier();
#endif
int i;
#if parallel
int j;
int tag = 0;
MPI::Status status;
MPI::Request requestIsend, requestIrecv;
#endif
// initialization
for ( i = 0; i < rowCounter; i++ ) {
vector = 0.0;
}
// possible local contribution
if ( localContribution == 1 ) {
for ( i = 0; i < rowCounter; i++ ) {
vector += vector_local;
}
}
#if parallel
MPI::COMM_WORLD.Barrier();
#endif
// broadcast filtered values and positions by all processors
#if parallel
for ( i = 0; i < MPI_Size-1; i++ ) {
for ( j = 0; j < counterFilteredList[MPI_SendList]; j++ ) {
MPI_Vector[j] = vector_local[ nodeToRow[rowToNodeFilteredList[j][MPI_SendList]] ];
}
if ( counterFilteredList[MPI_SendList] != 0 ) {
requestIsend = MPI::COMM_WORLD.Isend ( &MPI_Vector, counterFilteredList[MPI_SendList],
MPI::DOUBLE, MPI_SendList, tag );
requestIsend.Wait ( status );
}
if ( counterFilteredList[MPI_ReceiveList] != 0 ) {
requestIrecv = MPI::COMM_WORLD.Irecv ( &MPI_Vector_Buffer, counterFilteredList[MPI_ReceiveList],
MPI::DOUBLE, MPI_ReceiveList, tag );
requestIrecv.Wait ( status );
for ( j = 0; j < counterFilteredList[MPI_ReceiveList]; j++ ) {
vector[ nodeToRow[rowToNodeFilteredList[j][MPI_ReceiveList]] ] += MPI_Vector_Buffer[j];
}
}
}
#endif
#if parallel
MPI::COMM_WORLD.Barrier();
#endif
}