天天看點

共享的邊界如何覆寫獨享

今天讀了一位朋友寫的一篇關于linux排程域的文章,感到甚是有用,讀了以後發了一番感慨如下:

SMT共享了ALU,然而卻獨享了寄存器;MultiCore共享了L2 Cache,然而卻是獨享L1 Cache的;SMP共享了記憶體,然而每一個處理器卻是獨享Cache的;NUMA的所有節點共享了存儲陣列,然而每個節點卻是半獨享記憶體的;多台計算機共享了整個網絡,然而卻獨享着自己的記憶體,外設...整個網絡獨享着資料,然而卻共享了世界!這是一幅美麗的畫卷,如此和諧又如此對稱,這個畫卷反複重複着共享與獨享之間的合作而不是争奪,某些意義上,獨享是為了精确分工,而共享是為了不同工作者之間高效地合作。

資源的配置設定方式總是在各個層面影響工作的效率,資源的配置設定總的看來有兩種方式,一種是将一個資源獨占式的配置設定給工作者,這樣該資源隻能由它的屬主工作者利用,别的工作者完全通路,另外一種就是共享式配置設定,指的是資源可以由所有的工作者利用。如果确定性的,一個工作者使用的資源絕對不會被别的工作者使用到,那麼這個資源就可以獨占式的配置設定給該工作者,然而如果一個資源需要很多的工作者來通路,那麼就應該以共享的方式配置設定。自從分工開始以來,人類就面臨資源配置設定的問題,随着分工的細化,社會化生産成了一個時髦的詞,在工業界形成了流水線這樣的工程解決方案。分工就是為了更好的協作,為了更有效的産出,是以不可避免的要面臨工作者之間的通信問題,凡是涉及到這部分問題的資源就要以共享的方式進行配置設定,其實完全可以消除共享,用專門的通信規範進行工作者之間的通信,然而那樣的話會帶來很大的開銷,而共享資源的方式無疑是最高效的,因為對于工作者來說,用自己的東西肯定是最高效的,共享的東西對于每個工作者來講都是自己資源。

對于分工來講,無非兩種方式,一種就是消除時間上的浪費,另一種就是消除空間的浪費,後一種比較容易實作,無非一個屋子裡多安排幾個勞工罷了,我們對于空間的操控力總是強于對時間的操控力,對于消除時間的浪費就不是那麼容易了,我們必須将一個按照時間序列化的工作分解成好幾個可以按照空間展開的子工作,事實上我們人類生活在時間軸上,一開始就是在時間軸上序列化做事的,是以将一個工作分解成n個子工作很有難度,雖然有難度,但是難度還不至于大到不可想象,在數學上有統籌學,在工程上有流水線,這些都是這種思想的展現,這些方案中,最重要的就是分解的子工作沒有太多的共享資源,如果有的話就會産生共享資源的同步互斥問題,但是如果沒有的話,那麼這種分解就絕妙到了極點,完全可以消除資源共享。大千世界是很複雜的,不是什麼設計都是絕妙的,按照道理來講,不同的任務同時展開不應該用什麼共享的資源,畢竟它們是不同的任務嘛,但是世界的事物不是孤立,世界因聯通而精彩,是以共享資源的問題是不可避免的,不僅僅同一個任務的分解還是不同任務的并行。對共享資源處理的難度來自于我們對時間操作的難度,我們可以征服最高的山峰,可以征服太陽系甚至可以征服男人的下颚,可是我們卻征服不了時間,時間的流逝速度和方向我們隻有眼睜睜看着的份兒,是以對于分解的子任務,我們不能主動引導工作流何時使用共享資源,也無力扭轉不同的子任務對共享資源的依賴關系,唯一能做的就是當沖突發生的時候,要麼等待,要麼丢棄已有的成果盡自己最大的努力來使得一切看起來安然。

這世上本來沒有也沒有必要有共享資源,參與者多了也就有了共享資源,因為聯通使世界精彩。難道僅僅是聯通的因素嗎?其實還有一個因素就是為了高效,就是前面我說的,讓大家都使用的資源真的歸大家所有,任何工作者使用的時候就好比用自己的東西一樣友善,這樣可以節省很大的一筆資源重複建設的開銷,為此付出的同步互斥問題值得。

好了,最後我們來用一種更加獨特的眼光看一下資源的共享。前面說将單一的任務分解成不同的子任務之間或者不同的任務之間根本不需要共享資源,也就是說獨享為主,共享為次,但是如果将一件工作配置設定給不同的工作者來做,并且不是像前面那樣按照時間序列縱向分解而是橫向分解,然後将少的多得任務配置設定給不同的工作者,這種模式中共享卻比獨享來的必然,所有的子任務都是一模一樣地重複相同的事情,是以所有的資源都是共享的,但是這種分解有什麼意義?其實按照上面的叙述沒有什麼意義,因為上面強調的是一個大任務的分解方式,本質上的說法應該是增加人手做相同的工作,顯著的意義就是提高吞吐量,這個不用多說了吧。是以要麼按照縱向的方式将流水線橫向展開,然後并行化各個流水環節,要麼增加人手,提高吞吐量,前者如果分解的好的話不必太在意資源共享問題,而後者則必須考慮資源共享問題。第一段中列出的計算機的架構的例子說明了計算機系統是一個複雜的系統,在資源配置設定上兼用了橫向展開和縱向展開兩類。是以雖然硬體提供了如此好的機制,作業系統核心必須提供政策來最大化的利用這種優勢,最起碼不要将這種複雜的機制變成牽絆,對于linux核心,負載均衡就是幹這個事情的,為了負載均衡核心提供了排程域的概念,按照負載均衡的意義和代價将整個系統分為了多個排程域級别,其中最進階别的排程域中的負載均衡的代價最大,最低級排程域的負載均衡的代價最小,核心每各一段時間對各個排程域進行一次負載均衡,負載均衡代價越大的排程域其均衡間隔越大,因為核心為了盡量少付出昂貴的代價。核心的排程域的概念在軟體層面上再現了第一段的美麗畫卷的前半部分,也即是到NUMA的部分,作業系統核心的設計直接影響了上層軟體的性能是否按照硬體的本意來展現。

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1273963

繼續閱讀