資料結構與程式架構(三)

2021-06-21 09:26:55 字數 1387 閱讀 5159

在上篇文章中,我們看到了硬體工程師在設計程式(即邏輯電路)時是很直觀的,直觀就意味著容易理解和檢錯;同時,我們也能看到這種方法的強大,通過將基本處理單元連線成特定的拓撲結構,就可以實現某種特定功能的計算;而且,這也體現了這種方法的靈活性,當面對新需求時,我們只要設計出能處理這一新需求的拓撲結構即可;另外,值得一提的是,這種方法是高度模組化的,任何乙個處理單元都可以被另乙個功能相同(但經過優化)的單元替換,且即使(新單元的)介面有變化也沒有關係,我們只需要增加相應的其它處理單元即可。

以上這些優勢使得硬體程式普遍的比軟體的質量高而且穩定,如果我們能在軟體的架構設計中也引入這樣的方法,可以想像它能給我們帶來多大的好處!然而,這並不是乙個簡單的任務,困難主要來自於硬體程式和軟體程式的執行機制不同。

我們知道,在物理電路中,訊號可以通過併聯電路同時傳遞給不同的處理單元,然後在這些單元中進行並行的計算,硬體設計師只需要處理好不同處理單元間的訊號同步問題就可以了,正是這種高併發的物理特性,以及訊號同步的可控性,保證了即使邏輯電路的層次非常多,拓撲結構非常的複雜,程式也能夠高效且穩定地執行。

然而對於軟體程式來說,它具有典型的序列執行的特徵,即使現在我們的pc和智慧型裝置已進入了多核時代,但與大型軟體複雜的模組結構相比,其併發能力也是非常可憐的,而且這種併發控制目前都是由作業系統管理的,而作業系統對於乙個程式可併發執行的執行緒數量是有限制的,而且作業系統的整體效能也會受到乙個程式所建立的執行緒數量的影響,所以當乙個軟體的模組結構超出了這一限制,我們就不能簡單的通過增加執行緒來模擬硬體程式的執行機制了。那麼,此時我們要怎麼辦呢?

第一感的想法,是逐個的執行處理單元,然後把它產生的輸出傳遞到下乙個處理單元,如果我們的程式模組具有鏈式的結構,這種處理方法是可行的,但是如果是更加複雜的結構呢?比如乙個處理單元需要多個其它處理單元的輸出(即多對一結構),或者乙個處理單元會輸出到多個其它處理單元(即一對多結構),甚至乙個處理單元需要它自身或其它處理單元上一次執行的結果(即反饋迴路),深入思考一下這些情況,不難發現要決定下乙個處理單元將異常的繁瑣,而這也預示著這個排程程式(即程式的框架)將非常的複雜,而且容易出錯,很可能使得我們得不償失。所以,我們需要想想別的方法。

既然正向決定下乙個處理單元不行,那逆向行不行呢?即,我們先確定乙個最終輸出單元,然後看它的輸入緩衝區中是否有資料,如果沒有,就給它的所有輸入單元發出乙個訊號(這個訊號可以是乙個真實的資料訊號,也可以是乙個假想的訊號,即觸發某些操作,下文會有所體現),要求他們提供資料,然後它的所有輸入單元此時就變成了當前的輸出單元,然後逐個的檢查它們各自的輸入緩衝區,並重複同樣的過程,直到某個初始輸入單元或反饋單元。

不難想象,利用上面的過程,我們可以構建出一棵樹,來反映訊號傳播的路徑。而一旦我們得到了這棵樹,那麼從樹葉(即初始輸入單元或反饋單元)到樹根逐層去計算各自的輸出就是非常簡單的事情了(還是乙個深度優先的遍歷演算法)。如果你理解了這個演算法,是不是覺得一切問題都迎刃而解了呢?而這個演算法就叫「以需求驅動」的設計思想。

資料結構與程式架構(一)

我想 資料結構 這個術語對每個程式設計師都不陌生,像什麼 棧 樹 fifo list map 雜湊表 之類的概念我們在學生時代就已掌握,我想應該沒有哪個有經驗的程式設計師沒有應用過上面提到的那些資料結構吧!然而,通常我們應用這些資料結構,是把它當作存放待處理資料的容器,有多少人會把它和程式架構聯絡在...

Python筆記三 資料結構與程式結構

1 元組可以由不同的元素組成,每個元素的型別可以不同,可以巢狀,元組一旦建立不能再做修改 tunple name 元素1,元素2,tunple name 0 為a 2 元組有負數索引,1表示倒數第乙個元素 3 元組的子集tunple name m n 4 將元組中的值分別賦值給多個變數 a,b,c,...

資料結構與演算法(三)

變位詞是指兩個詞之間存在組成字母的 重新排列關係 如 heart和earth,python和typhon 為了簡單起見,假設參與判斷的兩個詞僅由小寫 字母構成,而且長度相等 詞1中的字元逐個在詞2中檢查是否存在,存在則標記防止重複檢查。如果每個字元都能找到,並且詞1詞2長度相同則是變位詞。否則不是。...