【轉】實施並行編程的五大障礙

近期看見一篇來自Intel的很有意思的分析文章,作者提到在他向45名與會的各公司程序員/開發經理/戰略師提問“什麼是實施並行編程的最大障礙”時,下面五個因素被提及的次數最多:遺留代碼(legacy code)、教育(education)、工具(tools)、對衆核趨勢的恐懼(fear of many cores)以及可維護性(maintainability)。文章雖然是一篇Intel Parallel Studio的軟文,但是其中提及的這五大障礙卻非常值得討論,下面是我對這五大障礙的一些粗淺看法,希望能起到一個拋磚引玉的作用,歡迎大家給出你們的看法。

1. 遺留代碼

衆所周知,怎樣把公司的那些遺留代碼給並行化是一件非常困難的事情。100K~1000K的代碼量都非常正常,而並行編程本身又是非常容易出錯的,一大堆諸如data race, dependency, non-deterministic, memory consistency, dead lock, serialization bottleneck, thread safe等的問題隨便哪一個拉出來都讓人頭大,更別說要高效可靠的並行化這些龐大的遺留代碼了。更困難的是很多遺留代碼還有編寫者已經離職,文檔註釋不全等問題,這無疑是雪上加霜。從成本上來講,如果能通過一些優秀的編譯器(例如Intel的ICC)自動並行化一些遺留代碼無疑是最省錢的,但是這種方法最大的缺陷就在於像Intel ICC這種自動型編譯器能自動並行化的代碼非常少,從而導致它能提供的性能優化非常有限,而且就算是真正能獲得speedup的代碼也有很多約束條件(例如loop的循環之間沒有dependence,並且該loop應該是一個程序熱點)。所以目前的現狀就是大量的遺留代碼並不能有效的被並行化,從商業的角度上來講,如果能有一種解決方案能在短時間內快速可靠的通過實施並行化讓遺留代碼在多核平臺上獲得10%~30%的性能提升,那麼它就已經能爲公司節省大量成本了。

2. 教育

第二大的障礙可能就是程序員缺乏並行編程方面的教育了。其實並行編程已經有二三十年的歷史,不過在多核CPU出現之前那些並行編程都是“專家”們的玩具。那時候的並行編程大都是跑在集羣、大型機或者服務器上,通過MPI(message passing interface)或者SMP(對稱多處理器,即一個主板上有多個單核CPU,屬於shared memory model)來完成並行計算。Pthread標準是1995年建立的,之後出來了Windows版的Win32 thread,後來又出來了“編譯指導”、面向data parallel模型的OpenMP(OpenMP 3.0加入了task parallel支持),task parallel的鼻祖Cilk,Intel的Intel Thread Building Block(task parallel),Java 1.5開始對多線程提供較好的支持(加入了Java Memory Model),近幾年隨着GPU的發展,Nvidia又開始搞CUDA(data-parallel),Apple一看不對,並行編程以後是主流啊,我得插一手,於是自己撐旗弄了個針對CPU和GPU混合編程的OpenCL,微軟一看也坐不住了也要隨着Visual Studio2010開始搞C#的並行庫,馬上C++0x也要加入多線程支持,甚至連老古董Erlang也因爲天生支持並行被重新熱炒,總之隨着摩爾定律在串行世界的失效,整個業界都開始被迫往並行編程方向發展。

可是對程序員來說呢是什麼情況呢?我們現在所接受的教育大都還是串行世界的那些算法和數據結構,高德納在一篇訪談裏說“在我看來,這種現象或多或少是由於硬件設計者已經無計可施了導致的,他們將Moore定律失效的責任推脫給軟件開發者,而他們給我們的機器只是在某些指標上運行得更快了而已。如果多線程的想法被證明是失敗的,我一點都不會感到驚訝……你聽說過有多少程序員對這種未來一片光明的機器抱有強烈的興趣?我幾乎沒有聽說過,除了他們的訴苦。儘管我們學院那些搞硬件的傢伙一直想讓我相信我是錯的”,可見硬件發展被迫向多核轉移直接導致程序員們免費的午餐已經結束了。那麼程序員現在受到良好的並行編程教育了嗎?很顯然,現在隨便問一個普通的程序員:“你覺得並行編程容易麼?”,十有八九會說“我覺得很難”。前一陣有人討論服務器編程用多線程好還是多進程好?其實根本原因就在於哪怕多線程有性能優勢,可是isolation的多進程模式能在programming productivity和performance之間找到比較好的折衷,所以國內很有服務器開發者都選擇了多進程(例如雲風)。從大趨勢上來講,不管是研究體系機構的,還是寫OS/Compiler的,還是定義編程語言的,現在都在積極努力的爲廣大的程序員提供一個更容易使用的並行編程模型,Intel這幾年不也在搞多核培訓麼,這都是好現象,但是,離真正的全民並行編程時代還有相當長的路要走。近幾年的IT技術熱門書單裏面很少有並行編程的書籍就是個很好的寫照。

3. 工具

工欲善其事,必先利其器。那麼現階段我們能用的,並且好用的並行編程工具有多少呢(歡迎大家補充)?

(1) IDE: Intel Parallel Studio,微軟馬上出來的VS2010算一個,Sun的Sun Studio(不知道它的未來如何,但是它本來就很小衆),Nvidia的CUDA平臺什麼的就先不算了
(2) Compiler: Intel的ICC(能自動並行化一些代碼),Nema Labs的FASThread(一套可以快速可靠的指導程序員實施並行化的解決方案,特別適合將遺留代碼並行化)
(3) Performance Tuning: Intel Vtune Analyzer(綜合性能分析),Thread profiler,Acumem的Thread Spotter(針對多核Cache的性能分析和優化)
(4) Debugging: Petra的Jinx

總體上我個人覺得它們對程序員來說確實有用,但是前提條件是你要會用。這其實又跟第二點“教育”有很大關係了。

4. 對衆核的恐懼

現在我們看到4核已經非常普遍了,等過幾年那可就是8核,16核,32核了。怎樣確保你的代碼在覈數倍增的趨勢下仍能有很好的性能,很好的可伸縮性?這真的是個問題。我現在所做的研究就是多線程程序中鎖競爭的性能分析,目的就是爲了幫助程序員更好的解決由鎖競爭造成的性能瓶頸。實際上,爲了得到很好的可伸縮性,程序員需要往往需要使用並行友好的數據結構(例如concurrent hash map),使用細粒度的鎖甚至無鎖編程,設計data parallel的算法,性能調優(例如典型的false sharing問題)等等等等,這其中每一項都是不小的挑戰。我曾經翻譯過的一篇文章對設計多線程程序提供了一些有用的建議

5. 可維護性

毫無疑問,我們希望並行代碼能夠與現存的runtime系統、build系統以及其他現有代碼一起正確的工作,我們更希望這些並行代碼易於理解、便於維護並且有較長的生命週期。可是現階段真正掌握並行編程的程序員少之又少,而且並行編程又是這麼困難,哪怕你對這些並行代碼只是做一些小小的改動都很有可能導致新的bug,新的性能瓶頸,那真的是一件非常痛苦的事情。

發佈了36 篇原創文章 · 獲贊 58 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章