軟體飛線
最近在和一個研究所的同事交流,談到把一個特性移到他們這裡來做的問題,我提到這個軟體飛線太多,不適合獨立拉出來給他們做。這位同事不能理解:什麼是“飛線太多”。這是一個架構問題,本文理一下這個邏輯。
構架設計和編碼都是邏輯設計,都是“如果XXX,就YYY”。區別在於,這個邏輯是否成立,編碼可以讓“計算機”進行測試,架構設計只能用“人腦”來進行測試。所以,架構設計領域濫竽充數的人特別多,因為可以“運行復雜邏輯”的腦子很少,“構架程式碼”不能跑,不具有可抽象性:程式碼是否正確,可以代理為:計算機是否輸出正確結果。架構邏輯是否正確,只能在腦子中一行行過。
所以,編碼是工作在非常穩固的“計算機介面”上的。架構是工作在非常不可靠,需要人為維護的“邏輯介面”上的。在編碼上破壞這種人為維護的“邏輯介面”,我就稱為“飛線”。這和硬體PCB的飛線的概念是一樣的:本來PBC已經把所有元器件如何互聯都定義了,但越過這個定義,直接在兩個點之間直接連了一根導線。原來在PCB上想好的訊號一致性,可靠性,應力,溫度控制,干擾,防靜電等等措施就不再對你有約束力。雖然可能你解決了一個問題,但其他設計就不可靠了。
舉一個現實的例子,以前的博文我聊過IOMMU的當前狀態:硬體可以支援多個程序(pasid),軟體只能支援一個程序,但多程序正在上傳。但我的驅動現在就要用。我們進行了這樣一個設計:
- 基本原則:核心使用裝置記憶體使用dma api;程序使用裝置記憶體使用iommu api
- 檢測到核心沒有pasid支援的時候,強制核心選擇其中之一,另一方不支援
其他細節我先忽略,有了這個原則的實施。我的高層(架構)設計就可以進行很多其他設計了,比如我可以做這樣的設計:如果我在另一個模組中發現核心沒有pasid支援,我可以認為實施這個原則的模組傳遞過來的裝置記憶體,一定是dma api分配的。
這個邏輯全部在文件或者在人腦中,編碼者為了實施他的特性,很容易就破壞它。比如在特定場合上,同時使用dma api和iommu api。雖然,很多使用我們會用自動化工具(包括程式碼結構)去保護我們的架構策略,但對於複雜系統來說,你不可能都靠這種方法,而且工具本身有工作量,靠工具制定的原則可能會變成架構負擔的。這時,我們只能靠模組的maintainer或者gate keeper去進行這種保護。這部分工作,就是系統的構架控制了。
而飛線,就是對這種保護的破壞。一個系統,如果飛線多了,架構控制就沒有了。你失去了系統中一個個可以被單獨依賴的邏輯,構架設計就成了一句空話。因為它的基礎沒有了。它只有每個具體情況的“如果”,沒有大部分情況的“如果”。你拿到一片記憶體,你就知道是個指標,它在不在實體記憶體中,裝置是否可以訪問,你能不能訪問,你都不知道。你在現在的平臺上可以訪問,換一個平臺,換一個時間還能不能訪問你都不知道。這怎麼建邏輯嘛。一旦系統成了這樣,你想把一個模組拉出去給另一個團隊做,這就完全沒有可能了。
很多人覺得架構設計和控制是不必要的,但在架構師眼中,一個個可依賴的邏輯和抽象被消滅,是直接看得見的。
所以,做飛線不是不可以——在戰地版本中做。同時,不要指望打完一場仗,戰地版本還能用下去。