主 題: 摩爾定律的末日-軟硬件性能提升的歷史和未來 [加為收藏] 第 1 篇 - 第 7 篇 共 7 篇 返回 作者:imissunow 時間: 2006.08.30 13:03 :0 朵 :0 個 免費大餐不久就將結束。對此,你有何打算,做好下一步準備了么? 對主要的處理器廠商以及架構,包括Intel、AMD和Sparc、PowerPC[譯注1]來說,改善CPU性能的傳統方法, 如提升時鐘速度和指令吞吐量,基本已走到盡頭,現在開始向超線程和多核架構靠攏。而且這兩個特性(特別 是多核)已經在部分芯片實現,如PowerPC和Sparc IV;Intel和AMD也將在2005年內趕上。2004年In- Stat/MDR秋季處理器論壇[譯注2]的主題就是多核設備,很多公司都展示了改進和新研發的多核處理器。不 過,要將2004年稱為多核年,顯然還不夠理直氣壯。 多核將引領軟件研發發生基礎性變化,特別對接下來幾年里那些面向一般應用、運行在PC和低端服務器上的應 用軟件(在今天已經銷售出去的軟件里占有很大比例)而言。在這篇文章里,我想就多核為何突然對軟件產生 重要影響,以及并發巨變如何影響我們和我們未來編寫軟件方式的問題展開討論。 我可以這么說:免費大餐已經結束一兩年了,但我們現在才開始意識到這個問題。 免費的性能大餐 業界存在一個有趣的現象:“安迪送,比爾取。”[譯注3]無論處理器性能提升多少,軟件都有辦法迅速吞 噬。CPU速度十倍于前,軟件就有十倍于前的活要干(或者肆無忌憚猛增軟件的工作量,導致性能下降)。在 過去幾十年里,由于CPU、內存和硬盤特別是CPU廠商強力推進主流系統向更新更快的方向發展,大多數軟件不 做版本升級,甚至原封不動,就可輕松而持續地享受處理器性能提升的成果。盡管時鐘速度不是衡量系統性能 的唯一和最好的標尺,但其重要意義不容忽視。我們見證了CPU的發展歷史:從500MHz到1GHz,然后再到 2GHz,不斷提高。今天,主流計算機已經進入3GHz時代。 不過,有一個很關鍵的問題:這種提升模式什么時候會走到盡頭?盡管莫爾定律預言了歷史上的指數式增長, 但我們很清楚指數式增長不可能永遠維持,因為硬件畢竟受物理極限約束;光速是不可能更快的[譯注4]。所 以增長必然放緩,最后停滯。順便說明一點,莫爾定律的主要描述對象是晶體管集成密度,但在一些相關的領 域,如時鐘速度方面,也出現了類似的指數式增長;甚至在別的領域有更快的增長速度,例如著名的數據存儲 量爆炸。不過這些重要趨勢需要另一篇文章來分析了。 如果你是一個軟件開發人員,那么你可能一直在免費享受桌面計算機性能提升的大餐。某些操作會成為應用程 序性能的瓶頸?“你過慮了”,我們對這樣的回答耳熟能詳,“未來處理器將更為強勁,而現在的應用程序速 度倒是日益被非CPU吞吐量和內存速度因素扼殺,比如I/O、網絡和數據庫等等。”真的是這樣么? 要在過去,這的確沒錯。但在以后,就完全不對了。 我有兩個消息要告訴大家。第一個是好消息,處理器性能仍然會不斷提高。第二個則是壞消息,至少在短時間 內,處理器性能的提升,不再能像以往那樣讓現在的應用程序繼續免費獲益。 過去30年里,CPU設計者主要從三個方面提高CPU性能,頭兩個就是從線性執行流程上考慮的: 1、時鐘速度 2、執行優化 3、緩存 提升時鐘速度將增大單位時間的時鐘周期數。讓CPU跑得更快,就意味著能讓同樣工作或多或少更快完成。 優化指令執行,可以在每個時鐘周期內完成更多工作。目前的CPU中,一些指令被不同程度地做了優化,如管 線、分支預測、同一時鐘周期內執行更多指令,甚至指令流再排序支持亂序執行等[譯注5]。引入這些技術的 目的是讓指令流更好、更快執行,降低延遲時間,挖掘每一時鐘周期內芯片的工作潛能。 在這里,有必要對指令再排序作個簡單說明。我剛才提到的部分指令優化手段,其實已遠非普通意義上的優 化。這些優化可能改變程序原意,造成程序不響應程序員的正常要求。這可是個大問題。CUP設計師都是心智 健全且經過嚴格訓練的好同志,正常情況下,他們連蒼蠅都不愿傷害,自然也無意破壞你的程序。而在最近幾 年里,盡管知道指令重組有破壞程序語義的風險,但為了提升每個時鐘周期內的工作效率,他們已經習慣于積 極開展這類有風險的優化工作。難道海德先生[譯注6]復活了?當然不是。這種積極性清楚表明,芯片設計師 承受了交付速度更快CPU的巨大壓力;在這種壓力下,為了讓軟件跑得更快,他們不得不冒改變程序意思,甚 至應用崩潰的風險。拿兩個有名的例子來說——寫操作再排序和讀操作再排序[譯注7]。允許處理器對寫操作 再排序是非常令人吃驚的,讓大多數程序員意外,一般來說這個特性必須關閉,因為在寫操作被處理器武斷地 再排序條件下,程序員很難保證程序正確執行。讀操作再排序也有明顯的問題,但大多數情況下這個特性是開 啟的;因為相對來說它更容易把握一些,而且人們對性能的要求,讓操作系統和操作環境設計師只能選擇讓程 序員在一定程度吃點苦頭,畢竟,這比直接放棄性能優化機會的罪責小一些。 第三個是增大與RAM分離的片內高速緩存。RAM一直比CPU慢很多,因此讓數據近可能靠近處理器就很重要—— 當然那就是片內了[譯注8]。片內緩存持續飚升了很多年,現在的主流芯片商出售的CPU都帶有2M甚至更高的二 級緩存。值得一提的是,今后,三種提升CPU性能的傳統手段里,增加緩存將碩果僅存。我會在后面更詳細說 明緩存的重要性。 我寫這么多的意思是什么呢? 最重要的是我們必須認識到,傳統性能提升方法與并發沒有直接關系。過去任何方法帶來的速度提升,無論是 順序(非并行的單線程或單進程)、還是并發執行的程序,都能直接受益。這點很重要,我們目前大量的程序 都是單線程的,而且在未來仍然有重要的存在價值。 當然,適當時候,我們重新編譯程序,可以利用CPU的新指令(如MMX、SSE[譯注9])和新特性提升系統性能。 但總的來說,即使放棄使用新指令和新特性,不做任何更改,老程序在新CPU也會跑得更快,讓人心花怒放。 曾經的世界是這般美好,可如今,她就要變了顏色。 為什么我們今天沒有10GHz芯片 其實,CPU性能提升在兩年前就開始碰壁,但大多數人到了最近才有所覺察。 我這里有份來自Intel的數據(當然你可以從其他廠商得到類似數據): 圖中反映了Intel芯片的時鐘速度和晶體管集成規模演變歷史。晶體管集成數至少就目前而言仍在繼續上升, 但時鐘速度的情況就不同了。我們從圖中可以看到,大概在2003年初,一路高歌猛進的CPU時鐘速度突然急剎 車。受制于一些物理學問題,如散熱(發熱量太大且難以驅散)、功耗(太高)以及泄漏問題[譯注10]等,時 鐘速度的提升已經越來越難。 你目前在工作站上用的CPU時鐘速度是多少?10GHz么? 2001年8月Intel芯片就達到2GHz,按照2003年前的 CPU發展趨勢推算,到2005年初,我們就能擁有第一塊10GHz的Pentium芯片。但實際上沒辦到。而且情況好像 越來越糟——我們根本就不知道到底在什么時候這樣的芯片可以出現。 那么放低期望,4GHz又如何呢?目前我們已到3.4GHz——那么4GHz已經不遠了吧?唉,好像4GHz也遙不可 及。可能你知道,Intel首先于2004年中將4GHz芯片的發布時間推遲到2005年,而到了2004年秋季,則徹底取 消了4GHz計劃[譯注11]。在本文寫作的同時,Intel宣布計劃到2005年早期,實現到3.73GHz(即圖中的右上 最高處)的微量提升。所以,至少就目前來說,時鐘速度的競賽實際上結束了,Intel和其他大多數處理器廠 商將把旺盛的精力投入到多核等方向去。 也許,我們某天在主流PC里能裝上4Ghz的CPU,但2005年別想。Intel實驗室里的確已經有運行在更高速度的 芯片——不過代價是驚人的,比如龐大數量的冷卻裝置。你想不久在你的辦公室里就有這樣的冷卻設備,坐飛 機的時候,就把它們放在你膝蓋上?別做夢了! 莫爾定律與新一代處理器 “沒有免費的午餐。”——摘自R. A. Heinlein的小說《The Moon Is a Harsh Mistress》 莫爾定律玩完了?這個問題很有趣,嚴格地講,還不能這么說。盡管和所有的指數式增長方式一樣,莫爾定律 總有一天會走到盡頭,但最近這些年,還沒有這樣的危險。芯片工程師在榨取時鐘周期內剩余價值時的確碰了 壁,不過晶體管集成量仍在暴漲,所以從這個角度說,CPU近期仍將遵循莫爾定律,系統吞吐量繼續提高。 關鍵的變化,即本文的中心,是今后幾代處理器性能提升所走的道路將完全不同。同時,大多數現在的應用軟 件將不再可能不作大規模重構,就能像過去那樣從處理器免費獲益。 接下來數年里,新型芯片的性能提升將主要從三個方面入手,其中僅有一個沿襲是過去的: 1、超線程 2、多核 3、緩存 超線程,是指在單個CPU內,并行兩個或多個線程。超線程CPU已經發布了,支持并行執行一些指令。不過這種 CPU還是存在短板,雖然給它增加了部分硬件如寄存器,但它和絕大多數普通CPU一樣,但緩存、整數和浮點運 算器仍然是唯一的。有資料表明,寫得較好的多線程應用,在超線程CPU上能獲得5%-15%的性能提升;假設趨 于理想狀態,即多線程程序寫得好到極點,那么性能可以提高40%。不錯了,不過還是做不到成倍提升,而且 對單線程應用毫無幫助。 多核,主要是指在一塊芯片上運行兩個或多個處理器。部分芯片如Sparc和PowerPC目前已經推出了多核版本。 Intel和AMD也計劃在2005年內初步實現,具體時間取決于它們的系統集成水平,功能則是一樣的。AMD初期在 性能設計可能更具優勢,如更好的支持功能同片內集成,而Intel基本上就打算將兩顆Xeon膠合在一塊芯片上 了事。所以剛開始的時候,這種雙核芯片與一個真正的雙CPU系統在性能幾乎沒有差別,僅僅在價格上前者更 為便宜,畢竟它的主板上不需要兩個插槽和額外膠合件;另外,即便理想狀態,這種架構也無法達到雙倍速 度,且無益于單線程應用,而只有寫得較好的多線程應用能得到好處。 最后一個是片內緩存,還能像預期那樣在近期繼續上升。三個方法中,僅有這個可以讓現有應用全面受益。片 內緩存有令人難以置信的重要性和對大多數現有應用的超高價值,原因很簡單,那就是空間就是速度。CPU和 主存交互的代價是巨大的,如果能避免,那就盡量不要和它打交道。在目前的系統里,從主存獲取數據所花時 間,通常是從緩存獲得數據的10到50倍。很讓人吃驚吧,因為很多人都以為內存已經足夠快。其實這不過是與 硬盤和網絡相比,而不是運行在更高速度的片內緩存。應用程序的工作與緩存間的適配程度,和我們是榮辱與 共的。很多年來,不重構程序,僅僅提高緩存大小就拯救了現有應用,給它們帶來新生。軟件操縱的數據和為 新增功能而加入的代碼越來越多,性能敏感的操作必須繼續與緩存適配。套用經濟大蕭條時期老人常念叨的一 句話:“緩存為王。” 順帶說件發生在我的編譯器小組的趣事,算是“空間就是速度”的一個佐證。32位和64位編譯器將同樣的代碼 分別編譯成32位和64位程序。64位CPU有多得多的寄存器和其他代碼優化特性,因此運行其上的64位編譯器先 天的獲得極大性能提升。這當然很好。而數據的情況又如何呢?換到64位平臺上,內存中絕大部分數據的大小 并未發生變化,唯一例外的就是指針,指針占用了兩倍于以前的空間。因此,我們的編譯器和絕大多數32位應 用相比,揮舞指針就費力得多。現在的指針耗用8個而不是4個字節,空間凈增加,結果我們發現64位編譯器的 工作集[譯注12]大小顯著增加。工作集增大導致性能下降,差不多抵消了更快的CPU和更多寄存器帶來的性能 優勢。就在我寫這篇文章的時候,64和32位編譯器正以同樣的速度運行,盡管程序代碼完全一樣而且64位處理 器先天能力更強。這就是“空間就是速度”。 緩存能,但超線程和多核CPU對現在的絕大多數應用,幾乎不會有任何影響。 綜上所述,硬件的變化到底會給軟件開發方式帶來怎樣的影響呢?你可能已經有了初步答案了。讓我們更深入 研究,明白其厲害所在。 對軟件來說,這意味一次巨變 上世紀90年代初,我們開始學著理解對象。在主流軟件開發領域里,從結構化到面向對象編程是過去20甚至可 以說30年來最重要的變革。這期間也發生了其他一些變化,例如近來誕生的的確讓人著迷的WebServices,但 我們中絕大多數人在職業生涯里從未有過見識像面向對象那樣基礎而深刻改變軟件開發方式的機會。 現在,機會來了。 也從現在開始,性能大餐就不再免費了。雖然托緩存增大的福,我們還能在半路上撿到普通的應用性能提升 丸,但如果你希望你的應用程序在新的處理器里能繼續獲得爆炸性的性能提升,那就需要你好好編寫并發程序 了(通常是多線程的)。說比做容易啊,也不是所有問題都天生可以通過并行解決,而且并發編程的難度也是 很大的。 肯定有人嚷嚷開了:“并發?并不是什么新鮮玩意嘛!人們不就已經在寫這樣的程序了么。”是的,小部分程 序員的確寫過。 別忘了,至少從上世紀60年代晚期的Simula開始,人們就在寫面向對象程序。但到了90年代,面向對象才成功 發動革命并奪取統治地位。為什么呢?工業是受現實需求驅動的,為了解決越來越大的問題,必須編寫越來越 大的系統,這樣的系統也需要越來越強勁的CPU和存儲設備支持,正好硬件系統也逐步提供了這樣的支持。面 向對象編程擅長抽象和依賴管理,所以成為了開發經濟、可靠和可重用的大型軟件的必備利器。 并發編程差不多也有同樣漫長的歷史可以追溯,很早的時候,我們就開始編寫協程、管程[譯注13]以及其他與 并發相關的東西。近10年來,我們也發現有越來越多的程序員在編寫并發應用(有多線程的,也有多進程的) 系統。但是發生整體轉向性的巨變,目前還不具備條件,需假以時日。現有大量的單線程應用,仍然有巨大的 存在價值,這點我會在后面說明。 說點題外話,當前“下一次軟件開發革命”這樣的詞語多如牛毛,總讓大家眼花繚亂,其實這是商家宣傳自己 新技術所作的廣告,不要理睬它。新技術通常都很吸引人,有時候也很有用,但軟件開發方式的重大變革必然 來源于在真正得到爆發式廣泛應用前就存在并經過多年緩慢成長、先進而穩定的技術。這個過程是繞不掉的。 變革所依賴的基礎技術必須足夠成熟(包括有固定的廠商和工具支持);通常,這個成熟穩定過程至少要花費 7年的時間,新技術在廣泛應用時才不會有潛在的性能懸崖和陷阱。所以,像面向對象這樣的軟件開發變革, 也必須在各項技術經過多年甚至幾十年磨礪后才能發生。即便在好萊塢,絕大多數的一夜成名,也仍然是多年 努力后發生重大突破的表面象征。 并發將是軟件開發史上的又一個重大變革。很多專家仍然在這個變革是否比面向對象還大的問題上爭論不休。 這樣的爭論最好還是留給學問家吧。技術工作者最感興趣的是和面向對象一樣,編程方式的變化程度、編程技 術的復雜性和學習曲線問題。 并發之正反二面 并發技術(特別是多線程)在主流軟件里大多應用在兩個方面。第一類是天然就彼此獨立的、邏輯上分離的控 制流程,比如在我設計的數據庫復制服務器里,每個復制Session都放在各自的線程里,彼此完全獨立的,不 會工作于同一條數據記錄上。第二類不像第一類那么常見。為了系統提升性能,像利用多CPU平臺的能力,挖 掘應用程序其他部分的潛能等,我們也會編寫并發代碼。在我的數據庫復制服務器里,多個獨立的線程在多 CPU平臺上就工作得很好。 然而,并發編程也是要付出代價的。一些很明顯的問題相對來說無關緊要,比如鎖定。對資源的鎖定降低了系 統的性能,但如果你能找到辦法最小化甚至消除資源共享,讓操作真正并行,從而明智得當地使用鎖,那么從 并發執行得到的收益,要遠大于在同步上蒙受的損失。 更重要的問題,大概就是并非所有應用都適用并行。這點我會在后面說明。 應該說,最大的問題,就是并發編程本身的難度了。程序員必須將腦子里的編程模型轉化為可靠的程序,這比 實現順序執行的傳統程序難得多。 任何學習過并發的人都認為自己已經理解并發,早早結束尋找他們認為不可能但實際潛在的競爭沖突和他們其 實仍沒鬧明白的問題。如果開發人員認真學習和思考并發編程,就會發現通過合理組織的內部測試能發現大多 數的競爭沖突問題,這個時候,無論是在知識水平還是心情愉悅度上,他們都能達到一個新的高度。不過,除 了經過理解為什么和怎么進行真正壓力測試的行家測試過的、已經正式發布的軟件,都會存在部分在普通測試 中無法捕獲的潛伏并發問題。這些問題只有在真正的多處理器系統上才會暴露出來,因為在這樣的環境里,多 個線程不是在單處理器上切換,而是真正的并發運行,大量新問題就會涌現。而偏偏又有很多人自以為已經真 正理解如何編寫并發程序,真是讓人忐忑不安啊。我見過不少項目組,他們的程序在很多用戶那里即便施以極 端苛刻的壓力測試,都能出色工作,但某天一個用戶部署了真正的多處理器機器后,深層次的競爭沖突甚至程 序崩潰問題馬上出現。CPU發展到今天,重構你的應用,讓它們多線程運行在真正的多核計算機上,的確像逼 迫初學游泳的人一下子跳入深水——直達終點,似乎有點殘忍,但只有真正并行的環境,才非常容易暴露出你 的問題。而且,即使你組織了一個能真正編寫可靠并行代碼的團隊,也不能說就不會出現問題。例如,并發代 碼運行可能非常安全,但(在多核的機子上)卻不比在單核的機子上跑得快。其典型原因就是線程未被合理分 離,共享了單一資源,造成程序執行順序化。這類問題是相當微妙而復雜的。 結構化程序員學習面向對象(什么是對象?什么是虛函數?我如何使用繼承?知道“是什么”和“怎么辦” 外,還得問一句“如何保證理論上正確的設計在實踐中的正確性”)是一個飛躍,同樣的,順序思維的程序員 學習并發(什么是競爭沖突?什么是死鎖?它是怎么出現的,我如何避免它?什么樣的構造在我看來是并行的 但實際上順序化了程序?在“是什么”和“怎么辦”外,還要回答同樣的問題“如何保證理論上正確的設計在 實踐中的正確性”)也是一個飛躍。 現在的大量程序員并沒有真正理解并發,就像15年前大量程序員沒有真正理解對象一樣。但并發編程模式是可 以學習的,尤其是我們要堅持基于消息和鎖的編程;一旦真正理解了并發,就會發現它并不比面向對象難多 少,很容易覺得那是自然而然的。我們需要為我們自己和我們的團隊做好訓練投資和時間的準備。 有必要說明一點,我在上面故意將并發編程模式限定在消息和鎖基礎上。其實也有在語言級就直接支持的無鎖 編程,比如Java5和很流行的C++編譯器。但對于程序員來說,無鎖比有鎖并發編程難得多。大多數情況下,只 需要系統和庫編寫者理解無鎖編程就行了,雖然事實上每個人都可以從無鎖系統和庫獲益。老實說,即便有鎖 編程,也有點碰運氣的味道呢。 對我們來說這到底意味著什么 好了,回到正題,將問題歸納一下。 1、我們已經討論清楚的、最重要結論是:如果應用程序想充分利用CPU吞吐增加量,那它們就必然日益需要并 發,這種形勢逐漸明朗,并將在接下來的數年里深入發展。Intel已經揚言未來他們會推出集成100顆內核的芯 片,那么單線程應用最多就只能利用這種芯片1/100的潛在生產力。“哦,性能沒那么重要吧,計算機總是跑 得越來越快”的論調已經變得天真而可疑,甚至在未來不久將完全錯誤。 目前,并不是所有的應用都需要(或者更準確的說,只有應用中重要的作業才需要)并行。像編譯這類的問 題,是必須要考慮并行的,而其他則不一定。請看這個有趣的例子:一個女人需要九個月才能生產一個小孩, 并不代表九個女人能花一個月生出一個孩子。你以前可能接觸過類似的推導,但又沒感覺這個問題意猶未盡 呢?如果有人再和你就此討論,我向你推薦一個刁鉆的問題:從這個命題你能斷定“女人-小孩”是一個非并 行問題么?通常,人們會下意識地認為它天然就不是一個并行問題,但實際上并不完全是這樣。如果目的是生 一個小孩,它的確是一個非并行問題;但如果是生產多個小孩,那么它就是一個標準的并行問題了!所以說, 目標不同,結論就大相徑庭。在考慮你的軟件是否和如何使用并行時,千萬別忘了面向目標原則。 2、可能不那么明顯的結論是:CPU將很可能日益成為應用程序性能的瓶頸。當然,不是所有應用都會這樣,那 么目前還未明顯受制于CPU能力的應用在未來雖然可能受到CPU影響,CPU也不會一夜之間成為它們的鐐銬。但 “I/O、網絡和數據庫瓶頸”似乎快走到谷底,因為在這些領域,條件仍然在迅速得到改善(如GB硬盤、WiFi 網絡等等);而與此形成對比的是,CPU性能提升技術已走到峰點。請注意,我們的CPU目前在3GHz徘徊。所 以,除了指望緩存在未來繼續擴大(這可真是一個大好消息),現在的單線程應用不太可能跑得更快。其他方 面的性能提升手段,雖然未來還可能繼續發揮作用,不過已經無法和過去相提并論了。芯片設計師正在拼命尋 找新辦法提高管線利用率,降低數據加載延遲,但在這些領域,長在低枝的果子早已被摘光。而應用程序新需 求的增加不但不稍事休息,反而神經質地加速猛沖。我們只好逼迫程序做更多的事情,而程序則只有威逼 CPU,壓垮它,除非程序能并發執行。 應對如此巨變,我們現在有兩條路可以走。一是面向并發重構應用,二是勤儉持家,小心規劃代碼,讓它吃更 少的食,干更多的活。這就引出了第三個有趣的話題。 3、提升程序效率、優化其性能將越來越重要,而不是相反。已經高度重視性能優化的語言將獲得新生,其他 的語言趕緊奮起直追,朝著效率和優化努力吧。面對長期增長的需求,希望面向性能努力的語言和系統能為我 們分憂。 4、最后一點,編程語言和系統將不得不盡快做好面向并發的準備。Java語言從一開始就支持并發編程,雖然 還存在不少問題以致不得不發布多個后續版本提升并發程序的正確性和效率。C++長期以來被用于編寫大型多 線程系統,但它卻沒有對并發的標準支持(ISO C++標準甚至有意未提及線程[譯注14] ),因此,并發目前只 能在一些不可移植的特定平臺和庫基礎上實現(而且實現還不夠完善,比如靜態變量只能初始化一次,這就要 求編譯器自動加鎖,但很多C++的實現里并不生成鎖)。另外,目前存在多種并行編程標準,比如pthreads和 OpenMP[譯注15] ,其中一些支持隱式并行,另一些顯式支持。讓編譯器分析單線程程序并自動生成并行代碼 的隱式并行方式當然美妙而優雅,不過這類自動轉化工具的結果代碼質量還無法與人工編寫的顯式并行代碼媲 美。目前的并發編程主要以鎖為基礎,這種方式也很難把握,常常要賭幾分運氣。總之,我們迫切需要一個比 目前語言提供的更高抽象層次的、統一的并發編程模式。關于這點,以后我還有更多的話要說。 總結 如果你以前對并發未加注意,那么現在是時候了,仔細分析應用的設計,挑出現在和不久就可能過于依賴CPU 能力的操作,研究這些部分如何從并發得益。你和你的團隊,現在也該深入學習和了解并發編程的要求、不 足、風格和專業概念了。 少部分應用天然適用于并行,但大多數不是的。即便你知道程序受制于CPU的位置,可能也很難找到將這部分 操作并行化的辦法。所有這些問題,要求我們趕緊對并行多加思考和研究。隱式并行編譯器能幫點小忙,但不 能指望太多,它不可能比得上盡你所能將順序化程序轉化為顯式并行和多線程版本后的效果的。 感謝仍未停止的緩存擴大和管線少量優化,免費飯菜在今后還能有一點,不過從今天開始,餐館無償提供的只 有小菜和飯后小點心了。菜譜上仍然有優質可口的魚片,但現在要享受它就得付費——設計精細化、代碼更復 雜,而且要加倍測試。對于多數應用來說,這是個好消息,盡管要辛勤耕耘,但回報是豐厚的,因為并發可以 讓應用繼續從處理器能力暴增中充分受益。 譯注1 處理器發展歷史上,精簡指令集(RISC,Reduced Instruction Set Computer)陣營曾向微特爾 (Wintel,Microsoft+Intel)陣營發動過三波聲勢浩大的微電腦盟主爭霸戰。 上世紀70年代以來,對處理器的要求更為全面,不單是提升速度就能滿足,比如低耗能、小體積,加強數值運 算、支持多媒體功能等。復雜指令集(CISC,Complex Reduced Instruction Set Computer)的微指令多 且長度不統一,造成解碼器線路復雜;加上受當時制造工藝的限制,如果在芯片上直接集成高速緩存和其他部 件,體積和價格都將變得難以想象。 RISC應運而生。因為RISC指令精簡、線路精簡,所以芯片體積和能耗降低,騰出空間也可容納更多寄存器;另 外指令定長,通過硬件加速,還可提升效能。RISC學術界從一開始就分為兩派:Berkeley RISC(伯克利大學 RISC計劃)和Stanford MIPS(斯坦福大學MIPS計劃。MIPS,Microprocessor without Interlocked Pipeline Stages,無內部互鎖流水級的微處理器。我國龍芯即MIPS架構)。 Sun公司引進了RISC技術,在此基礎上制定了Sparc(Scalable Processor Architecture,可擴展處理器體 系結構)微處理器體系結構規范,并于1985年推出了相應處理器。1988年,Sun領頭組建了Sparc聯盟,口號 是“RISC + UNIX vs CISC + DOS”,藉此發動第一次爭霸沖擊。后因市場遲遲未見銷量,加上Sun在技術上 又留了一手,導致聯盟最后只剩Sun自己和德州儀器。 1990年,MIPS研究開花結果,開發團隊成立了同名公司MIPS,并于1991年建立了ACE(Advanced Computing Environment)聯盟,主要成員有Digital(迪吉多)、SGI(Silicon Graphics,視算科技)和Compaq(康 柏)。Compaq當時市場低迷,且Intel對Compaq展開了游說,因此Compaq最先退出了聯盟;而Digital又忙于 Alpha芯片的開發。主要成員離心離德,1992年,第二次聯盟以SGI收購MIPS草草收場。 IBM從1975年開始精簡指令集芯片研究,也就是后來的PowerPC。1992年,IBM與Motorola(摩托羅拉)、 Apple Computer(蘋果)宣布合組Power聯盟。剛開始,Power聯盟引用學界評比論文,直指x86復雜指令 集結構無法應付未來信息需求,而媒體也紛紛發難斥責x86電腦效能低劣,操作介面不便,都表示支持大膽 改革的Power聯盟。形勢危機,當時Intel的總裁葛洛夫甚至認為Intel已陷入死亡之谷,如果應對失措, “Intel”將成為歷史名詞。Power聯盟洋洋得意。 但在接下來的三年里,Power聯盟遲遲不能統一平臺標準,操作系統開發進度也嚴重滯后。到1994年,Intel 推出了Pentium芯片,微軟的Windows 95也大功告成。盡管當時的Pentium遜于PowerPC,Windows 95界面也 不如Macintosh,但前二者相互支援,前后兼容,不斷改進,而后二者卻不夠統一,用戶沒有安全感。形勢急 轉直下,Power聯盟大跌眼鏡。 第一波攻擊,Sun退回到工作站;第二波攻擊,SGI退回繪圖工作站;第三波攻擊至今,IBM還在服務端處理器 領域靠PowerPC苦撐。 順帶說一句,Intel和AMD主要走的都是CISC路線。但處理器發展到現在,各方面技術已經相互融合,不存在絕 對CISC或者RISC的芯片了。 譯注2 In-Stat:www.instat.com,全球著名的行業研究機構,Reed Business Information出版集團成員公司之 一,Reed Elsevier的戰略組成部分;涉及半導體、電信和電子消費品等領域的研究、評估與預測。 MDR:MicroDesign Resources,原屬美國Ziff-Davis電子出版集團,1999年被Reed Elsevier收購。 In-Stat/MDR主辦《Microprocessor Report》(《微處理器報告》)雜志,三周刊;Microprocessor Forum(微處理器論壇)每年10月在加利福尼亞州San Jose舉行。 譯注3 原句為:Andy giveth, and Bill taketh away. Andy:Andy Grove,安迪·格魯夫,1968年和羅伯特·諾宜斯(Robert Noyce)、戈登·摩爾(Gordon Moore)共同創立Intel。 Bill:Bill Gates,比爾·蓋茨,1975年和保羅·艾倫(Paul Allen)創立Microsoft。 譯注4 大概是2001年看到過一則新聞,到網上搜了一下,內容大致如下: 澳大利亞教授韋伯領導的研究小組利用位于夏威夷的世界最大的天文望遠鏡“凱克”觀測17顆不同的類星體。 由于這些類星體距離地球120億光年,它們在宇宙形成初期發出的光線到今天才抵達地球。在長途旅行中,部 分光線被星系間的氣云吸收。光線的吸收情況既能反映星系氣云的性質,也能反映出光的變化情況,這其中就 包括光的速度以及決定光速的光譜線精細結構常數。結果,韋伯等人發現,精細結構常數發生了微小的變化。 從理論上說,這意味著光速有可能發生過改變。消息公布后,不少物理學家對此發現持謹慎態度。韋伯及同事 希望用位于智利的另一個大型天文望遠鏡來證實他們的結果,據稱要得出最終結論尚需2至3年的時間。 不過到目前為止,似乎還沒看到他們的最終結論。 譯注5 管線:pipelining,或流水線。CPU的管線并不是數據輸入輸出使用的物理線路,而是指指令執行的流程。一 條指令必須被分解為多個執行步驟,每個步驟占用一個時鐘周期。例如最基礎的管線是5級的:(1)取指令, (2)對指令譯碼,(3)演算出操作數,(4)執行指令,(5)將結果存儲到高速緩存。前三步由指令控制器 (ICU)完成,后兩步由運算器(ALU或FPU)完成。管線可以細化,例如蘋果的G4處理器采用了7級管線, AMD 2500+處理器10級,Intel公司的P3到10級,P4到20級,P4-E甚至高達31級。管線加長,則每級任務量減 小,執行所需時間縮短,因此時鐘周期可以縮短,即時鐘速度加快。設管線為N級,時鐘速度為TMIPS(T百萬 次/秒),那么平均完成一條指令所花費時間為N/T(當然要求芯片的確在每個周期內能完成各管線級的任 務),因此理論上只要時鐘速度加快,則芯片處理能力上升。但問題是管線執行時總有出錯(如分支預測失 敗)的可能,一旦出錯,整個管線就要全部清空,然后從第一級重新執行,在這種情況下,長管線的全部花費 時間通常比短管線多。這就是部分AMD部分芯片比Intel相同甚至更高主頻的芯片實際速度要快的原因。 分支預測:branch prediction。解決管線中條件轉移引起管線停頓的問題。例如第一條指令是條件轉移,那 么需要等其判斷結果出來后才能執行下一條指令,分支預測可預測判斷結果,然后盡快執行其他指令,從而不 致管線停頓。當然預測也有出錯的時候,預測失敗將導致管線清空,從頭執行。目前預測準確度可達90%,進 一步提高分支預測準確率是正在研究的重要課題。 亂序執行:out-of-order execution。解決管線中指令相關引起管線停頓的問題。后序指令需要正在執行指 令的結果,因此無法立即處理后序指令,這叫做指令相關,造成其他處理單元的停頓,白白損失時鐘周期。解 決辦法是立即找出其他不相關指令來執行,最后由重新排列單元將各執行單元的結果按原來指令順序重新排 列。很顯然,亂序執行是有風險的。 譯注6 出自美國電影《化身博士》(Dr. Jekyll and Mr. Hyde,有1931和1941兩個版本)。故事講述哲基爾醫生相 信每個人都同時擁有兩極化的個性——好的一面與邪惡的一面。如果將這兩種個性分開成為截然不同的兩個 人,這兩個靈魂都將獲得釋放。他隨后成功地用化學實驗將自身邪惡的一面轉化成為海德先生,此先生犯下了 可怕的罪行。但當他想要停止用藥時,卻驚恐的發現一切為時已晚…… 譯注7 讀/寫操作再排序都屬亂序執行。看下面一段原始指令代碼: (p1)br label //分支判斷。若為true則跳轉到label,否則繼續執行 ld8 r9 r5 //從r5所指地址空間讀取8個字節到r9 add r2 r9 r3 //將r9和r3中值求和,并存入r2 其中ld,load;r,register。 因為load操作較耗時間,通常花費幾個時鐘周期才能完成。因此從提高效率的角度看,應該在處理器空閑的情 況下,盡早加載此操作。比如簡單再排序優化后: ld8 r9 r5 (p1)br label add r2 r9 r3 如果分支判斷結果為false,流程發生跳轉,那么可以直接舍棄r9的結果值,即ld8白做了;但如果未發生跳 轉,則ld盡早執行,提高了流程整體效率。 當然,CPU實際工作遠比上面例子復雜。比如將ld提前,但如果ld失敗怎么辦?有依賴關系的指令呢,能否亂 序?在多線程應用里,亂序還可能引起其他一些問題,比如Java中的Double-Checked Locking失敗。 不光CPU支持亂序執行,現在的很多編譯器也開始做亂序優化,而且重心有逐漸從硬件轉到軟件的趨勢。 有兩篇資料可以參看:Scaling Itanium® Architecture for Higher Performance(特別是其中的如何處 理指令依賴值得了解)和Verified Optimizations for the Intel IA-64 Architecture。 譯注8 片內,英文為on the die或On-Die。Die:裸芯;Chip:包裝后的芯片。類似有On-Chip、Off-Die/Chip。 譯注9 MMX:MultiMedia eXtension,多媒體擴展。Intel在1996年3月份正式公布了MMX技術的細節,并于1997年1 月正式向全球推出基于MMX技術的166MHz和200MHz Pentium芯片,AMD也幾乎在同時推出了支持MMX技術的第 六代處理器AMD K6。 MMX技術是Intel針對×86體系的一次重大擴充,使計算機同多媒體相關任務的綜合處理能力提高了1.5~2 倍。它不僅是Intel自 i386面世以來對CPU體系結構的一次顯著改進,同時也是IT界對多媒體數據處理等專用 芯片及功能板卡的一次成功挑戰。 SSE:Streaming SIMD(單指令多數據) Extensions,是Intel針對AMD K6-2引入的“3D NOW!”技術,于 l999年在Pentium3中引入的SIMD擴展指令集,業界也稱為MMX2,在多媒體數據處理(特別是3D)和浮點運算 等能力上全面加強。 譯注10 目前頻率最高的處理器是Intel P4 570J,3.8GHz,上升非常緩慢。 CPU頻率越高,所需電能和發熱量越多;而晶體管越小,耗電和熱量越低。制造工藝進步,可能讓晶體管更 小,從而讓CPU在相同或一定程度內提高的能耗下達到更高頻率。從這個角度說,提升CPU頻率的瓶頸是制造工 藝。 于是,Intel推出了了90nm工藝的Prescott核心Pentium4,其理論頻率將能達到6GHz!然而世事難料,在 90nm工藝晶體管里,由于電介質厚度太低無法阻擋電子的穿越,造成了嚴重的電流泄漏問題,隨之帶來的就是 大量的電能消耗和廢熱。如果強行提升頻率,則發熱激增,CPU經不起如此的高燒。 泄漏電流問題并非不可解決,但絕不能在短時間辦到。至此,芯片廠商提升系統性能的思路開始發生重大變 化,即轉向多核。 有關電流泄漏和應對策略的詳情,可參看:NetBurst的繼承者 Core微處理器架構技術解析。 譯注11 在IDF05(Intel Developer Forum 2005)上。Intel首席執行官Craig Barrett就取消4GHz芯片計劃一 事,半開玩笑當眾單膝下跪致歉 譯注12 Working Set,記錄了操作系統為進程提交的內存的總量。 譯注13 并發編程語言(Concurrent Language)中的術語。 協同程序(coroutines),或協程。用以實現協作式多任務,于上世紀60年代提出。同屬一個協程的多個進 程,在同一時刻只能有一個處于運行狀態。協程屬于一種并發進程創建方式,其他方式還有Fork/join、 Cobegin/coend和進程顯式申明(Process declarations)等。 并發進程之間的通信方式主要有兩種方式:變量共享(shared variables)和消息傳遞(message passing)。其他還包括抽象于更高層次的遠程過程調用(remote procedure call,RPC)等。 通信就離不開同步。同步方法主要包括:信號量(semaphores)、條件臨界區(conditional critical regions)、管程(monitors)、互斥(mutual exclusion)、路徑表達式(path expressions)、原子事 務(atomic transactions)和匯集(rendezvous)等。 其中的管程是位于低級同步控制手段之上的一種對象化管理工具。信號量的使用是無結構的,很不方便;條件 臨界區相對于信號量更結構化,但同步控制代碼仍然非常分散,不利于管理。因此引入了管程,它實現了共享 資源的集中管理,封裝了共享資源以及施于其上的操作。 譯注14 因為某些原因(如競爭條件下靜態變量初始化問題),線程還未被列入ISO C++標準。目前在不同的平臺上, 都有線程的專門實現,短時間內難以完全統一。 不過Boost線程庫目前差不多具有準標準身份。 譯注15 并行編程中必須考慮的兩個問題是被處理數據和任務間通訊。經過用戶的選擇與市場的淘汰,現在的并行編程 標準基本上趨向以下三種: 1、數據并行。特點,各任務處理的數據彼此分離,任務間通過消息傳遞進行通訊;數據分離和消息傳遞工作 由編譯器完成。 HPF(High Performance Fortran,高性能Fortran)是典型的數據并行編程語言。因為目前的編譯器技術對 實際應用中各種不規則問題的解決方案仍不夠理想,加上專注于數據并行,因此HPF未獲廣泛應用。 2、消息傳遞。特點,各任務處理的數據彼此分離,任務間通過消息傳遞進行通訊;數據分離和消息傳遞工作 由程序員和用戶完成,因此對程序員要求很高。這種模式非常適用于消息傳遞的體系結構(如機群系統),用 戶和程序員主要需考慮的是通訊同步和通訊性能問題。 并行虛擬機(PVM,Parallel Virtual Machine)和消息傳遞接口(MPI,Message Passing Interface) 是兩種廣泛使用的消息傳遞并行編程標準。其中PVM側重異構環境下的可移植性和互操作性;MPI更強調性能, 但在異構環境下有不同的實現。幾乎所有的高性能計算系統都支持PVM和MPI。 3、共享內存。特點,各任務處理的數據實現內存共享,任務間也通過共享數據實現通訊;數據共享可由程序 員或編譯器完成。共享內存并行編程主要應用在對稱多處理器(SMP ,Symmetric Multi Processors)系統 上。 OpenMP(Open MultiProcessing由X3H5發展而來)和PThread(POSIX Thread)都是共享內存并行編程的實 現。 OpenMP由1993年建立的X3H5標準發展而來,目前已成共享內存并行編程的實際工業標準,得到DEC、Intel、 IBM和Sun等廠商廣泛支持。它在Forthan、C/C++得到了實現,主要支持隱式并行編程,即編譯器實現并行。 PThread主要在Unix系統上使用。Unix的實現系統很多,比如Linux、FreeBSD、Solaris、Mac OS X等。要 在眾多“類UNIX”上開發跨平臺的多線程應用,絕非易事,因此制定了POSIX Thread標準。Addison Wesley (Boost庫發起者之一,ISO C++標準委員會成員)的《Programming with POSIX Threads》這本書,可以 說是Unix上編寫多線程應用的必備參考書。對其他平臺并行程序開發也有很高參考價值。 總的來說,共享內存并行編程與目前大多數的多線程程序員思維習慣最為接近,是程序員從單核轉向多核系統 需付代價最小的方案。但專家仍有不同意見,比如Herb Sutter就不看好OpenMP,因為共享內存并行編程本質 上并沒有太多改進,仍然依賴數據資源的鎖定,這會帶來性能問題。消息傳遞并行有性能優勢,但對程序員的 要求又太高了。所有這些難題,還需要研究并行和各種標準、庫的專家繼續努力解決。 --- ※ 來源: 齊魯熱線虛擬社區 http://club. [FROM .*] 作者:imissunow 時間: 2006.08.30 13:04 :0 朵 :0 個 回復【 imissunow 】: 原文于2005年3月發表在Dr. Dobbs Journal,被Rickard Oberg(J2EE奇才,JBoss作者)認為是 2005年度世界最重要技術文章之一。文章深刻分析了處理器性能提升技術的發展歷史與未來趨勢、并發的重要 性及其與軟件的關系,以及現階段并發編程中存在的主要問題。文章特別強調:軟件開發史上,自面向對象降 生以來的又一個巨變已經叩向我們的房門,那就是并發。 --- ※ 來源: 齊魯熱線虛擬社區 http://club. [FROM .*] 作者:imissunow 時間: 2006.08.30 18:02 :0 朵 :0 個 回復【 imissunow 】: 譯文敘述深刻而生動、分析到位、不失風趣。實為揭示“后摩爾時代”軟硬件相輔相成發展趨勢的精彩 好文! “安迪送,比爾取”=“Intel送、微軟取”——指我們大家購買的PC機處理速度越來越快,更快的CPU 價格卻更便宜,這就是摩爾定律帶給我們的實惠。而微軟操作系統從95到XP、longhorn越來越大、越來越占用 資源,更龐大的操作系統得以運轉的基礎就是更快的CPU。顯然微軟也從摩爾定律得到了實惠。 文中指出按照CPU主頻從幾百M達到1G、2G、3G的跨越速度(大概是2002年-2003年間的事情),2006 年的今天我們應該已經得到接近10G速率的CPU,而事實是從4年前CPU達到1G,今天我們常見的CPU速率頂多3G 左右,CPU主頻提升速度確實幾乎停滯! 文章也揭示了今后軟件效率提升之道,那就是并發:多線程編程或者說多進程編程!SUN的J2EE有與生具 來的天賦,最常見的JSP實際上就是多線程運行的,只是很多編程新手并沒有注意到這一點。 --- ※ 來源: 齊魯熱線虛擬社區 http://club. [FROM .*] 作者:imissunow 時間: 2006.10.12 16:06 :0 朵 :0 個 回復【 imissunow 】: ABCNews.com報道,眾所周知的摩爾定律被英特爾驗證是有效的,并被人們認為能在半導體行業里繼續 存在下去。而摩爾第二定律則成為軟件廠商最大的隱患,因為按照摩爾的這兩條定律可以發現,軟件更新的速 度很難趕上硬件。 幾乎每一個生活在這個現代社會里的人都聽說過摩爾定律(Moores Law),它甚至成為了這個數字時代的基 礎,也成了我們日常生活中的節拍器。 但是肯定很少有人聽說過摩爾的“第二”定律。在接下來的幾年里它將會被證明比第一個定理還要重要。 事實上,如果這兩個定律繼續繼續存在,那么它們將會給微軟這樣軟件巨頭帶來災難。 摩爾定律是硬件革新步伐當中的重要主題,并陪伴著落后的軟件行業繼續前進。這大概就是微軟一再推后 發布新系統并帶來眾多麻煩的原因之一。 展望未來,革新步伐的不一致不僅僅會影響軟件和電腦市場,同時一些一科技為基礎的產品比如飛機、手 機、電視甚至MP3播放器,這些人們每天需要的東西都會受到或多或少的影響。 根據行業分析機構Venture Development Corp.的估計,所有目前正在正在進行著的項目當中,大約有一 半都要落后與預定的時間,超出的時間平均為四個月。同時更糟的是,我們目前新產品的革新速度已經開始逐 漸變的慢下來,這些都是以我們舒適的生活、娛樂甚至健康為代價的。 40歲的“定律” 我們把摩爾定律稱為摩爾的第一定律。你肯定還記得它的內容,就是半導體芯片的精度將會以18到24個月 為周期翻倍。這個定律是由高登·摩爾(Gordon Moore)于1965年提出的,他是Fairchild公司和英特爾公司 的聯合創始人。摩爾的預言因為65納米芯片的出現而被證明是繼續有效的,同時摩爾定律還被認為至少能在半 導體領域里存在20年甚至更長的時間。這個定律不僅適用于存儲芯片,在微處理器方面也表現的相當好,從手 機到個人電腦甚至到遺傳學,幾乎所有的領域都要用到它。 這將真正地告訴了我們摩爾定律在我們的生活中的重要地位,無論我們是不是知道它。 那么第二定律到底是怎么一回事呢? 幾乎沒有人知道摩爾在寫有第一定律的那張紙上的另一個定律,它只是一個很短的段落,盡管描述的不是 很清楚甚至很深奧,但是他仍然有力地向我們形容了什么是第二定律。它是這樣說的:“我們可以花更小的代 價建立出更大的系統,而且它的功能也會很龐大,它由很多相關聯的部分組成。它能實現非常龐大的功能,而 且這種功能會和設計和結構緊密地結合在一起,它可以讓這些巨型系統的制造商快速并經濟地設計和構造出各 種各樣的設備。” 大概一年前,我在《連線》雜志上再次重新看到了這段話,給我的感覺就是一段關于電子設備效率的晦澀 難懂的話。而且正像摩爾第一定律還不是一個真正正確的定律,但是芯片制造商們向消費者允諾,稱他們會盡 可能地保持技術發展的速度,所以摩爾第二定律也要被提倡做出類似的允諾:任何電子系統的整體效率每24個 月翻一番。 盡管《連線》雜志的這篇文章稱這些電子設備需要更好的電池來提供能量,不過我認識到了對于這個高科 技的世界里的一些其他東西,摩爾第二定律對它們的意義將更加深遠。 軟件必須要趕上硬件的步伐 單憑經驗來考慮,芯片的性能翻倍,軟件就需要以四倍的速度增長。而且根據摩爾第一定律,芯片的性能 每隔兩年都會發生飛躍性的改善,那么代碼的數量將會每隔一年就增加一倍。不幸的是,這種事情不會成為現 實。 環顧周圍,你會發現任何一個地方都會有這種問題出現。目前手機使用的代碼平均為200萬行,到2010年 會增加到1000萬行。如果根據摩爾定律來看,電視所需要的代碼將是這一數字的兩倍。而目前的汽車需要的代 碼數量平均為3500萬行,到2010年這個數字會突破1億行。 而現在這些數不清的科技產品將得不到足夠的發展,因為根據摩爾定律,硬件的發展速度遠遠跟不上軟 件。這當然會對去年那些堂吉訶德式的商業行為產生影響:為什么微軟這個依靠開發和銷售操作系統的軟件巨 頭,在它的下一代操作系統Vista上屢屢受挫。Vista的延期發布就像是拋錨了一般,尤其是戴爾。但是微軟還 是一次又一次的推遲發布。 硬件和軟件之間的這種差距在繼續拉大,它讓人們越來越覺得不安,同時它的惡化速度也會越來越快。 盡管這樣,但是我們沒有浪費一丁點時間。摩爾定律會繼續影響著整個行業,有力并無情地要求更多科技 行業不斷創造奇跡。 --- ※ 來源: 齊魯熱線虛擬社區 http://club. [FROM .*] 作者:imissunow 時間: 2006.10.29 21:58 :0 朵 :0 個 回復【 imissunow 】: 單純提高頻率來提高性能,已經被證明是錯誤的想法 X86通用處理器走到今天,已經面臨一個分水嶺了,INTEL徹底拋棄Netburst架構和摩爾定律,全面轉向 Core架構,INTEL重新迎來了一個光明的未來。 2年內,Netburst完全輸給了HAMMER,Pentium 4雖然有極高的頻率,但是并沒有帶來高性能,相反,卻 帶來了高功耗和高發熱,在零售市場一敗再敗。INTEL宣稱Netburst架構可以發展到10G主頻成為一個笑話。 那接下來怎么辦?既然單純提高頻率已經被徹底否定,接下來的發展方向在哪里呢?INTEL對外界的回答 是多核。那讓我們來看看多核吧。 最早出現的雙核處理器,是AMD是X2系列。INTEL為了對抗AMD的雙核,早早推出了Pentium D805和820, 可惜這個早產的Pentium D8XX系列架構同樣非常糟糕,INTEL只是簡單的將2個Netburst架構的Pentium 4簡 單的整合在一起,2個核心之間的二級緩存沒有共享,2個核心工作的時候,必須通過擁擠的北橋來交換數據, 這樣無疑大大的拖累了系統的運行速度。而且Netburst架構的高能耗,高發熱再一次得到體現,Pentium D820的TDP高達110W,而AMD推出的雙核處理器Athlon X2系列則在設計時就考慮了這個問題,2個核心共享二 級緩存,這樣在效率上大大超過了Pentium D,而且基于HAMMER的優秀架構,Athlon3800+ X2的最高TDP僅為 89W,更有低功耗的65W版本,同功耗的效率,幾乎比Pentium D性能要高30%。即使是最近發布的Pentium D915,65NM的工藝,性能也不過和AMD的Athlon3600+ X2相當,在浮點運算方面仍然落后于Athlon3600+ X2 5-10%。 Conroe系列處理器的發布,為INTEL在X86處理器市場挽回了一絲面子。2年來,一直被AMD的大錘 (HAMMER)架構壓制著的INTEL,在DIY市場,份額不斷降低,OEM市場,AMD已經得到了廣大集成商的青睞, DELL,HP,LENOVO,這三家世界上最大的集成商,均生產了基于AMD處理器的電腦,在中低端服務器市場, Opteron讓ITNEL的XEON相形見拙。這一切,隨著Core架構系列處理器的發布,INTEL終于重新鞏固了業界霸 主的地位。 Core核心,拋棄了Netburst架構,直接從P6(Pentium 3時代的架構)基礎上重新設計,并借鑒了INTEL 位于以色列海爾法實驗室(著名的Pentium M就是這里設計的)的經驗,采取了較短的14級流水線,并使用了 5個新技術:寬區動態執行(相比以前的X86處理器增加了一組解碼器,解碼器總數達到了4組,AMD以前嘗試過 沒有成功放棄了),高級智能告訴緩存(雙核心共享二級緩存,加寬了每個內核的帶寬),高級數字媒體增 強,智能內存訪問,智能功率特性。以上努力使得到目前為止,Conroe成為地球上最強的X86處理器。INTEL 進一步宣稱,將在未來幾年內發布多核,甚至百核的處理器。試圖以多核來提高處理器的性能,同時有不致讓 處理器功耗和發熱成倍增長。 AMD對付Conroe的利器,是降價,但是降價畢竟不是長久手段,這是損人不利己的辦法,沒得辦法的辦 法。AMD基于K8L新架構的處理器,得等到明年2季度才能發布,根據目前的解密信息K8L的浮點運算單元將比 目前的HAMMER增加一倍,并且將采取模塊化設計,原生4核,和65NM工藝。但是從目前看,似乎仍然無法超越 Conroe,頂多是打個平手。為此,AMD祭出了大旗——HT3和協處理器。 HT,即HyperTransport,是AMD 1999年提出的一種總線技術,是一種為主板上的集成電路互連而設計的 端到端總線技術,目前市面上銷售的AMD的處理器,都是基于HT2連接的。目前的HT,類似于INTEL的FSB (Front Side Bus前端總線)。以前這一點,只有InfiniBand和光纖通道做得到,但是這2者都需要通過獨 立的控制器實現,而且CPU和CPU之間是無法直接溝通的。而HT2時代AMD的Opteron處理器在服務器領域高速發 展的原因之一就是因為在一個服務器內不管有多少個處理器,通過HT2,總能保持高效工作和卓越的協作效 率。 而HT3,則不僅僅是主板上各部件的端到端總線技術和各個處理器之間的連接,HT3可以擴展到多個處理器 連接的同時,還擴展到多個服務器系統之間的連接,即多部服務器可以HT3標準的線纜聯結在一起,,由于HT3 控制器由CPU提供,這意味著無論集群內有多少枚處理器,彼此都是通過HT3來直接溝通,這樣就確保了優良的 協作效率,從而非常簡單的構建服務器集群。而且,HT3是彈性的,OEM廠商可以迅速的調整集群內服務器的數 量,而不必考慮更多的技術問題,這就讓哪些技術實力不強的PC廠商也有能力開發銷售自己的服務器集群產 品。而大型的基于HT3技術連接服務器,還可以用于大規模科學運算,模擬核實驗,氣象預測等等領域,這些 領域到目前為止都是RISC處理器的天下,X86無法插足。HT3的出現將改變這個現象。AMD的HT3的出現,將是 計算機領域的一次革命,他不僅僅威脅到INTEL,而且還威脅到了IBM,SUN,HP等公司在該領域的存在。計算 機領域將重新洗牌的可能性非常大。 協處理器,則是AMD在收購了ATI公司以后提出來的一個概念,代號為Torrenza。 關于AMD Torrenza平臺技術:該新平臺允許兩顆處理器(CPU或GPU)以協處理器架構同時運行,將把下 一代多核心64位處理器的效用再次提升。Torrentza的設計為開放式架構,它以Opteron處理器為基礎,支持 使用“Accelerators(加速芯片組)技術。可縮短CPU、芯片組、內存之間的通信延遲,實現系統的提速,并 向第三方芯片組廠商開放。而協處理器可以通過HT3總線連接,換句話說,以后的電腦,如果你覺得性能不 足,你可以如同插入USB設備一般,加一個CPU或GPU,而不必要重新購買主板等等,讓你的整機性能獲得質的 飛躍。 寫在最后: INTEL和AMD是目前世界上2大半導體巨頭,控制著世界上90%以上的X86處理器的生產和銷售。 INTEL在Conroe發布后,在2006秋季IDF上公布了新的4核處理器,代號為Kentsfield,該處理器是將2顆 Conroe封裝在一起,每個雙核的Conroe單獨享用4M的二級緩存,在某些方面,性能比Conroe提高了30-40%, 而TDP僅僅為130W而已。跟Pentium D可以看平。這里足以看出Conore的架構之優秀。 AMD則沒有僅僅關注處理器本身,他把目光放得更遠,力圖構建一個基于HT3.0為核心的新的計算機體系。 如果INTEL不拿出及時有效的對付方案,僅僅關注處理器本身的發展,在未來新一波的計算機技術發展過程 中,不免將再次落入下風。 引用資料:微型計算機10月上期硬派講堂,10月下期產品與評測。 --- ※ 來源: 齊魯熱線虛擬社區 http://club. [FROM .*] 作者:imissunow 時間: 2006.10.31 20:45 :0 朵 :0 個 回復【 imissunow 】: 通過堆棧調用解析多線程 首先說明一下,堆是進程的全局數據內存存儲區,棧是函數的局部數據內存存儲區。由于大多數書籍在介 紹堆或棧時,皆以堆棧泛指,因此,題目標題亦如此表述,希望讀者不要混淆就是了。 初見標題,也許有人覺得奇怪,多線程和堆棧有關系嗎?初學多線程,很多概念難以辨清。要全面深入理 解多線程,必須對棧有十分清楚的理解。個人感覺在Windows編程中,棧的概念猶如C/C++中的指針,非常重 要,但難于全面理解。市面上的書籍對堆棧的介紹或是蜻蜓點水、浮于表面;或是過于理論化,不夠具體,不 易理解。在這里,我以示例的形式將自己的一點學習體會寫出來與大家分享。為了便于表述清楚,文章分為兩 部分:第一部分介紹棧的調用,這是此篇文章的核心。第二部分解析多線程的概念。 一、棧的調用 眾所周知,在函數調用過程中,參數的傳遞是通過棧完成的,具體到機器碼是什么樣子呢?不同的調用約 定(PASCAL約定或STDCALL約定等)將導致不同的參數壓棧順序,這些細節就略去不講了,有興趣的讀者可以 參考相關書目。為了把棧的概念表述清楚,這里將涉及到一些簡單的匯編語言方面的知識,一點點而已。然后 以一個簡單的C++控制臺程序為示例來進一步詳細說明。先把代碼列出來,夠簡單吧。 #include int fn(int n) { n+=1; return n; } void main() { int i=1,j=10; i=fn(i); // A j=fn(j); // B cout< 在A處,進程的主線程調用了函數fn并傳遞了參數。其匯編代碼如下: 004010B6 mov eax,dword ptr [ebp-4] //此時ebp=0x0012ff80,&i=0x12ff7c,ebp-4為i的地址 004010B9 push eax 004010BA call @ILT+20(fn) (00401019) 再明顯不過了,第一行匯編代碼將變量i的數值放入寄存器eax中。第二行匯編代碼將變量i的數值壓入棧 中,對應前面(1)。第三行匯編代碼執行call指令,此條指令自動將返回地址壓入棧中,然后,跳轉到函數 體內部,準備執行函數內部的代碼,對應前面(2)。 現在我們再來看看函數內部的代碼是什么樣子。這里只截取部分相關代碼。 2: int fn(int n) 3: { 00401050 push ebp 00401051 mov ebp,esp … … … … 4: n+=1; 00401068 mov eax,dword ptr [ebp+8] //此時ebp=0x12ff20 &n=0x12ff28 eax=1 0040106B add eax,1 0040106E mov dword ptr [ebp+8],eax 第一行匯編代碼對應前面(3)。第二行匯編代碼對應前面(4)。第三行匯編代碼將變量n的數值放入寄 存器eax中。第四行匯編代碼將其加一。第五行匯編代碼將結果放回變量n。這里可以十分清楚地看到,EBP寄 存器用于參數的尋址。 現在我們再看看B處函數調用的情況。 004010C5 mov ecx,dword ptr [ebp-8] //此時ebp=0x12ff80,&j=0x12ff78 ,ebp-8為j的地址 004010C8 push ecx 004010C9 call @ILT+20(fn) (00401019) 可以看到,除了壓棧數值變化以外,沒有其它不同了。A處壓棧i,B處壓棧j。 下面使用VC單步調試,再來看函數體內部,匯編代碼沒有任何不同,不同的只是棧。當然了,函數體的代 碼是編譯器一次性編譯的。即使被多次調用,去完成不同的工作,不同的只是參數(調用棧),函數內部使用 間接尋址,只是相同的機器碼操作不同的內存存儲區而已。 2: int fn(int n) 3: { 00401050 push ebp 00401051 mov ebp,esp … … … … 4: n+=1; 00401068 mov eax,dword ptr [ebp+8] //此時ebp=0x12ff20 &n=0x12ff28 eax=10 0040106B add eax,1 0040106E mov dword ptr [ebp+8],eax 到了這里,棧的概念就講完了。 二、解析多線程 這里首先要明確一點:每一個線程都獨立擁有一個棧。 我們知道,Windows系統是一個多任務操作系統,多個線程可以“同時”執行。前面講到,CPU執行程序 代碼完全依靠各種寄存器。當一個線程將被掛起時,當前的各種寄存器的數值就被存儲在了線程的棧中。當 CPU重新執行此線程時,將從棧中取出寄存器的數值,接著運行,好像這個線程從來就沒有被打斷過一樣。正 是因為每個線程都有一個獨立的棧,使線程擁有了可以“閉門造車”的能力。只要將參數傳遞給線程的棧, CPU將擔負起這塊內存存儲區的管理工作,并適時地執行線程函數代碼對其進行操作,所有這一切與前面所講 述的沒有不同。當系統在多個線程間切換時,CPU將執行相同的代碼操作不同的棧。 下面舉一個例子來加深理解。 隨著面向對象編程方法的普及,我們很樂意將任何操作都包裝成為一個類。線程函數也不例外,以靜態函 數的形式將線程函數放在類中是C++編程普遍使用的一種方法。通常情況下對象包括屬性(類變量)與方法 (類函數)。屬性指明對象自身的性質,方法用于操作對象,改變它的屬性。現在有一個小問題要注意了。類 的靜態函數只能訪問類的靜態變量,而靜態變量是不屬于單個對象的,他存放在進程的全局數據存儲區。一般 情況下,我們希望每個對象能夠“獨立”,也就是說,多個對象能夠各自干各自的工作,不要相互打擾。如果 以通常的方法,以類(靜態)變量存儲對象的屬性,可就要出問題了,因為類(靜態)變量不屬于單個對象。 現在怎么辦呢?如何繼續保持每個對象的“獨立性”。解決的方法就是使用棧,將參數傳遞給線程函數的局部 變量(棧存儲區),以單個對象管理每個線程,問題就解決了。當然了,解決方法是多種多樣的,這里只是為 了進一步解釋多線程與對象的關系。 由于Windows的內部實現實在是太復雜了,這里只是在應用的層面上對棧給出解釋。若深入到Windows內 部,棧的定位首先需要依據寄存器SS經由(全局或局部)段描述符表得到相應的線性地址(虛擬地址)基址, 此基址與EIP相加,然后再經由分頁機制尋址物理內存。有興趣的讀者可以參閱文章后面的參考書目。一點學 習體會寫出來與大家分享,有不對的地方,歡迎指正。 參考書目: 《Intel匯編語言程序設計》(第四版),作者:Kip R.Irvine,電子工業出版社翻譯出版。 《Windows環境下32位匯編語言程序設計》,作者:羅云彬,電子工業出版社出版。 |
|