最近工作之餘研究數值演算法,覺得一些傳統問題還有優化空間。以C++試作了一些程式後,決定轉用fortran作為主力開發的程式語言。稍微讀了一些教學,以及一些試寫,想趁著新鮮感寫些心得。
雖然這未必是主流的看法,但我認為學習新的程式語言的成本其實很低。昂貴的是不同圈子的生態系,而不是程式語法。所謂的程式語言生態系其實涵蓋很多面向,例如它的適用環境(伺服器、桌機、手機、GPU、還是瀏覽器?),應用情境(遊戲開發、資料應用、網頁後端、科學模擬、機器學習等等),以及與之相映的工程師社群。好比說,要用網頁原生語言javascript來寫手機遊戲不是做不到,但效能以及精緻度就是遠遜專為手機特化的程式。與其硬是想如何讓javascript寫出漂亮的手機程式,還不如從頭學手機程式該怎麼寫。
數值程式是最早的程式種類之一,甚至可以說它比電腦的存在還古老(電腦出現之前,會以人工迭代數字來進行演算)。電腦的萌芽時期(1940–1970),以電腦來計算彈道、火箭控制、微分方程等是主流,程式是以組合語言寫成。1957年起,fortran誕生,它是一個專為數值計算特化的語言。我認為時至今日,要在超級電腦上計算大型數值程式,fortran應該還是遠勝其他語言的生態系,包含python, julia, matlab, C/C++等等。
以小型的數值程式而言,今日我們其實有多種選擇。熱門的選項包含python, julia, matlab, R等。如果你的演算法相當高階,意即不需要寫多層複雜的loop就能驅動,那以上數種語言挑喜歡的去用就好。當程式需要高效能的迴圈時,才需要在C/C++/fortran當中做選擇。
我自己認真比較C/C++/fortran,以及相關的生態系及程式實作(lapack, fortran BLAS, openblas)後,結論如下:如果目標是組合語言級的高效能程式,那麼應該用C/C++甚至是組合語言來撰寫;不過此類程式大多已經被openBLAS及其他BLAS實作涵蓋了(apple accelerate, intel MKL, cuBLAS, etc.)。如果目標是要寫演算法,那麼fortran對這類程式的開發,語法及生態系都要比C/C++還要友善。
舉例來說,一個二維的矩陣在fortran 90及以上的版本,相當容易表達、更動、平行化、以及在函式間傳遞。如果是C,那你必須傳遞矩陣的維度給函式;如果是C++,雖然有Eigen這類函式庫來處理矩陣,但撰寫相關的函式其實比想像中還要繁瑣的多。fortran這方面比起C/C++有多方便呢?numpy/matlab上常見的array slicing,fortran直接內建在語法之中。換言之,fortran一定程度上跟python/matlab一樣方便,但速度遠勝python/matlab。
我自己接觸過的程式語言相當多。我學到最重要的事情之一,就是硬要把別的語言上的生態系搬到自己熟悉的語言上,通常痛苦程度遠高於學習一個新的程式語言。這理由也不難理解:搬生態系時有很多未知的麻煩,即便上網查也不一定能找到解答。相對的,學一個新的程式語言碰到問題時,上網查一下就能找到給新手的解答。如果問題比較複雜,在原生生態系當中也有比較高的機率找到其他人如何處理類似的問題。這些好處,真的遠勝要學新的程式語言的學習門檻。