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
}