1965年,美國科學家,企業家,英特爾公司創始人之一的戈登·摩爾撰寫了一篇長達三頁的論文,闡述了電子產品市場對集成電路的整合影響,并預測集成電路中元件數量每年至少增加一倍,而這個過程將持續至少十年。1975年,他修正了這一預測,指出集成電路中的元件數量每兩年翻一番。 并持續到2012年左右。
一些公司預見摩爾定律預測的速度會放緩,開始研究增加計算能力的替代方法。 俗話說,必要性是創新之母,所以多核處理器就是這樣誕生了。
這看起來像是解決摩爾定律邊界問題的一種聰明方式,但是計算機科學家很快就發現自己面臨著另一個定律的局限:以IBM360系列機的主要設計者阿姆達爾命名的阿姆達爾定律。
阿姆達爾定律指出,系統中對某一部件采用更快執行方式所能獲得的系統性能改進程度,取決于這種執行方式被使用的頻率,或所占總執行時間的比例。于是阿姆達爾致力于并行處理系統的研究。
例如,假設你正在編寫一個基于GUI的程序:用戶將看到一個界面,點擊某些按鈕,并發生一些事情。 這種類型的程序受到管道中一個非常大的連續部分的限制:人員交互。 無論為此程序提供多少內核,它總是受限于用戶與界面進行交互的速度。
現在考慮一個不同的例子,計算pi的數字。多虧了spigot算法,我們可以很容易地將其劃分為并行任務。在這種情況下,通過為程序提供更多的內核可以獲得顯著的收益,并且新問題變成了如何組合和存儲結果。
阿姆達爾定律幫助我們理解這兩個問題之間的差異,并幫助我們確定并行化是否是解決系統性能問題的正確方法。
對于這種類型的并行問題,建議編寫可以水平擴展的應用程序。 這意味著可以使用程序的實例,在更多的CPU或機器上運行它,雖然這會導致系統的運行時間提高。 以這種方式構建程序非常簡單,你可以將大塊問題發送給應用程序的不同實例。
在21世紀初,當一種新的范式開始出現后,橫向擴展變得容易得多:云計算。 盡管有跡象表明這個詞早在20世紀70年代就已經被使用過了,但是21世紀初,這個概念真正在時代精神中扎根。 云計算意味著一種新的應用程序部署及擴展的規模和方法。 云計算替你配置物理設備,替你安裝軟件,替你進行維護,這意味著你可以訪問龐大的資源池,這些資源池將按需提供到機器中供工作負載使用。 物理設備對使用者變得可有可無,并且配備了特別適合他們將要運行的程序的特性。 通常(但不總是)這些資源池被托管在其他公司擁有的數據中心中。
這種改變引發了一種新的思考。 突然之間,開發人員相對低成本的具備了大規模的計算能力,他們可以用它來解決大型問題。 解決方案現在可以輕松跨越許多機器甚至訪問到全球。 云計算為以前那些只有技術巨頭才有資格解決的問題提供了一套全新的低成本解決方案。
但云計算也帶來了許多新的挑戰。 調配資源,在設備之間進行通信以及匯總和存儲結果都成為需要解決的問題。 但其中最困難的是弄清楚如何同時對代碼進行建模。 部分解決方案可能在不同的機器上運行,這一情況加劇了建模問題時常見的一些問題。 這些問題很快就造就了新的解決方案,可伸縮網絡。
網絡通常希望能夠通過添加更多應用程序實例來處理數十萬(或更多)的同步工作負載,這使得滾動升級,彈性水平可伸縮體系結構和地理描述等成為必備屬性,與此同時,這種解決方案還在編譯和容錯兩方面引入了新的復雜度。
因此,我們發現,現代開發人員可能有點不知所措。2005年,ISO C++標準委員會主席,C++/CLI首席架構師Herb Sutter為Dobb博士撰寫了一篇文章,標題為“免費午餐結束:軟件并發的根本轉向”。 標題貼切,文章有先見之明。 Sutter最后表示,“我們迫切需要一種更高層次的并發性編程模型,而非當前語言所能提供給我們的。”
如果想明白為什么Sutter有如此的“迫切感”,我們必須研究為什么并發很難得到正確的結果。
* * * * *
學識淺薄,錯誤在所難免。我是長風,歡迎來Golang中國的群(211938256)就本書提出修改意見。
- 前序
- 誰適合讀這本書
- 章節導讀
- 在線資源
- 第一章 并發編程介紹
- 摩爾定律,可伸縮網絡和我們所處的困境
- 為什么并發編程如此困難
- 數據競爭
- 原子性
- 內存訪問同步
- 死鎖,活鎖和鎖的饑餓問題
- 死鎖
- 活鎖
- 饑餓
- 并發安全性
- 優雅的面對復雜性
- 第二章 代碼建模:序列化交互處理
- 并發與并行
- 什么是CSP
- CSP在Go中的衍生物
- Go的并發哲學
- 第三章 Go的并發構建模塊
- Goroutines
- sync包
- WaitGroup
- Mutex和RWMutex
- Cond
- Once
- Pool
- Channels
- select語句
- GOMAXPROCS
- 結論
- 第四章 Go的并發編程范式
- 訪問范圍約束
- fo-select循環
- 防止Goroutine泄漏
- or-channel
- 錯誤處理
- 管道
- 構建管道的最佳實踐
- 便利的生成器
- 扇入扇出
- or-done-channel
- tee-channel
- bridge-channel
- 隊列
- context包
- 小結
- 第五章 可伸縮并發設計
- 錯誤傳遞
- 超時和取消
- 心跳
- 請求并發復制處理
- 速率限制
- Goroutines異常行為修復
- 本章小結
- 第六章 Goroutines和Go運行時
- 任務調度