陳教授來的時候,是個大晴天。
九月初的北京,熱浪從地面蒸起來,把遠處的樓宇烤得發虛。
一輛草綠色的吉普車停在紅星所門口,陳教授從副駕駛下來,手裡拎著一個軍綠色的帆布包,包帶在肩上勒出一道深痕。
他穿著短袖白襯衫,領口的扣子解了一顆,露出曬得黝黑的脖頸。
頭髮花白,但梳得一絲不苟,眼鏡片後面的眼睛不大,卻很亮,像兩顆打磨過的黑石子。
宋顏教授和呂辰已經等在門口。
“陳教授,辛苦了。”宋顏迎上去,接過帆布包,沉甸甸的,裡面全是資料。
陳教授擺擺手,在臺階上站定,抬頭看了看主樓上“紅星工業研究所”幾個大字,然後低頭看了看錶:“不辛苦,時間緊。機房準備好了?”
“準備好了。”
“資料庫的框架寫完了,我今天把微程式裝上,跑通之後,你們就可以開始填資料了。”
他頓了頓:“另外,汪教授那邊的分散式排程微程式也編譯好了,存在二維卡里,我一併帶過來了。”
他又補了一句:“三百多張卡,裝了兩個箱子,在後備箱裡。”
宋顏眼睛一亮:“微程式也好了?”
“好了。”陳教授一邊往車子後面走,一邊說,“汪教授帶著人熬了六個多月,排程器的核心程式碼寫了1萬多條指令。已經在計算機所的模擬環境裡跑通了基本功能,任務分發、負載均衡、結果回收。但還沒在你們這個16節點的真機上跑過。今天一併試。”
三個人走到後備箱,兩個木箱子和那個帆布包,一人抱一個,往右附樓走。
機房的鐵門開著,冷氣從門縫裡溢位來,在走廊裡凝成一層薄薄的白霧。
陳教授站在門口,沒有立刻進去,而是先透過門上的玻璃窗往裡看了幾秒。
“好。”他輕輕說了一個字,推門進去。
冷氣撲面而來,乾燥,帶著一種電子裝置特有的氣味,焊錫、松香、還有一點臭氧。
陳教授把帆布包放在管理員桌上,宋顏教授和呂辰把兩個木箱子放在地上,撬開蓋子。
裡面是碼得整整齊齊的二維卡,每一張都用牛皮紙信封封裝,信封上貼著標籤,寫著程式模組名稱、版本號、日期和負責人簽名,信封裡還有具體的指令文字。
字跡工工整整,一絲不苟。
陳教授從帆布包裡抽出一沓厚厚的資料,翻開第一頁,是一張手繪的系統架構圖。
中央是一個大方塊,寫著“排程器”,周圍圍著16個小方塊,代表16臺KJ-0A,線纜連線成星型和環型的混合拓撲。
“我先講一下整體設計。”他把圖紙攤在管理員桌上,宋顏、呂辰、諸葛彪、錢蘭、曾祺、陳工都圍過來。
“分散式輔助設計系統,分成三層。”
他豎起一根手指:“最底層,是硬體和通訊。16臺KJ-0A,星型網連儲存櫃,環狀網做協同。這一層你們已經跑通了,我不多說。”
豎起第二根手指:“中間層,是排程器。跑在16臺機器中的一臺,我們叫它‘主控節點’。它負責任務的接收、分解、分發、監控、回收。工程師坐在任何一臺終端上提交一個模擬任務,排程器會根據當前各節點的負載,決定把任務分給哪臺機器去算。算完了,結果返回給終端,同時存入儲存櫃。”
他頓了頓,豎起第三根手指:“最上層,是應用軟體。標準單元庫的資料庫管理程式、版圖編輯器的互動程式、模擬器的前端介面。這些是你們紅星所要自己寫的,理論組只提供底層呼叫的介面。”
陳教授講得很細,從任務佇列的資料結構,到節點負載的衡量標準,到故障節點的檢測與隔離。
呂辰一邊聽一邊在筆記本上記,偶爾提問。
錢蘭問的是資料一致性,如果主控節點把同一個任務分給了兩臺機器怎麼辦?
陳教授說排程器裡有一個“任務去重表”,每個任務有唯一編號,分出去之前先查表,分出去之後立刻寫入。
諸葛彪問的是環網通訊的可靠性,如果令牌在傳輸過程中被幹擾了怎麼辦?
陳教授說微程式裡實現了超時重傳機制,傳送方發出令牌後啟動定時器,如果在規定時間內沒收到應答,就重發。連續三次失敗,就判定節點故障,啟動隔離流程。
其他人也紛紛提問。
一個小時後,方案講完了。
陳教授合上資料,看著所有人:“有問題嗎?現在提。等裝上去了再改,麻煩。”
沉默了幾秒。
呂辰說:“有一個問題。如果主控節點自己宕機了怎麼辦?”
陳教授看了他一眼,嘴角微微翹了一下:“這個問題,汪教授想到了。所以排程器不是單點,而是雙機熱備。兩臺機器同時執行排程器,一臺主用,一臺備用。主用每十秒鐘向備用傳送心跳。如果備用連續三次沒收到心跳,就自動接管。工程師終端上的任務提交介面有兩個地址,主用連不上就切備用。”
他從資料裡抽出一張圖,是雙機熱備的狀態轉移圖,畫得清清楚楚。
“還有問題嗎?”
沒人再問。
“好。那就開始裝。”
先裝儲存櫃上的資料庫系統。
陳教授從帆布包裡拿出一個防靜電盒,開啟,裡面是一塊陶瓷封裝的只讀儲存器晶片,銀灰色的外殼,表面印著白色的絲印字。
“資料庫的核心,固化在這塊晶片裡。插到中央儲存櫃的背板上,上電之後會自動載入到指定記憶體區域。”
呂辰接過晶片,用拇指摩挲了一下封裝表面,然後走到中央儲存櫃後面,找到背板上預留的插槽,小心地插進去。“咔嗒”一聲,到位。
陳教授走到管理員桌前,按下監控終端的電源開關。
顯示器亮起來,綠色的字元開始跳動。
他敲了幾行命令,螢幕上的輸出一行一行地滾過:
LOADING DATABASE KERNEL……
KERNEL LOADED AT 0x1000
BUFFER POOL……
BUFFER POOL SIZE:64KB
INDEX STRUCTURE……
B+ TREE ROOT CREATED
DATABASE READY.
陳教授又敲了一個命令,螢幕上出現了一個簡單的提示符:DB>
他回頭看了一眼呂辰:“資料庫核心跑起來了。接下來裝管理工具。”
他從帆布包裡拿出一個牛皮紙信封,裡面裝著厚厚一沓二維卡,每張卡上打滿了孔。
他把卡片一張一張地塞進讀卡機,每塞一張,讀卡機就“咔嗒”一聲把卡片吞進去,顯示器上逐行顯示載入資訊:
LOADING ……DONE
LOADING ……DONE
LOADING ……DONE
……
載入了將近二十張卡,最後螢幕上出現了一行提示:ALL TOOLS LOADED. TYPE HELP FOR COMMANDS.
陳教授敲了“HELP”,螢幕上列出十幾個命令:
REATE_TABLE、INSERT、SELECT、UPDATE、DELETE、、DROP_INDEX……
“資料庫的表結構我已經建好了。”他切換到另一個介面,螢幕上出現了一個表格狀的輸出:
TABLE:CELLS
COLUMNS:
ID (INT, PRIMARY KEY)
NAME (CHAR(32))
FUNCTION (CHAR(16))
TECH (CHAR(4)) // 5UM OR 2UM
LAYOUT_DATA (BLOB)
SIM_MODEL (BLOB)
(BLOB)
VERSION (INT)
MODIFIED_BY (CHAR(32))
MODIFIED_AT (TIMESTAMP)
“每個標準單元存成一條記錄。ID是唯一編號,NAME是單元名稱,FUNCTION是邏輯功能,TECH是工藝版本——5微米還是2微米存版圖的座標資料,SIM_MODEL存模擬模型的引數,存測試向量。VERSION、MODIFIED_BY、MODIFIED_AT是版本管理用的。”
陳教授轉過身,看著呂辰:“你們的人要做的,就是對著手冊,把每個單元的這幾項資料,用IMPORT工具一條一條地塞進資料庫。IMPORT工具支援從文字檔案批次匯入,你們可以先把資料寫成文字檔案,再一次性匯入,比一條一條敲命令快。”
呂辰點頭,在本子上記下來。
資料庫裝完了,接下來是分散式排程微程式。
陳教授走到一號機前面,開啟機櫃門,從帆布包裡拿出另一個防靜電盒,裡面是一塊只讀儲存器晶片。
“排程器的微程式,固化在這塊晶片裡。插到一號機的介面板上。一號機就是主控節點。”
呂辰接過晶片,插到一號機介面板上的預留插槽。
陳教授走到操作檯前,按下電源開關,插入引導卡,讀卡機“咔嗒”一聲。
顯示器上的字元開始跳動:
LOADING SCHEDULER MICROCODE……
MICROCODE LOADED AT 0x2000
TASK QUEUE……
NODE TABLE……
DETECTING NODES……
螢幕上出現了一個表格,16行,每一行對應一臺KJ-0A。第一列是節點編號,第二列是狀態,第三列是IP地址(他們用簡單的數字編號代替IP)。
NODE 0 STATUS:ONLINE ADDR:0
NODE 1 STATUS:ONLINE ADDR:1
……
NODE 15 STATUS:ONLINE ADDR:15
16臺機器的狀態全是“ONLINE”。
陳教授點了點頭,又敲了一個命令:
START HEARTBEAT
螢幕上開始每隔十秒跳出一行:
HEARTBEAT:ALL NODES RESPONDED
HEARTBEAT:ALL NODES RESPONDED
HEARTBEAT:ALL NODES RESPONDED
排程器的主控節點開始向其他十五臺機器傳送心跳包,每一臺都正常響應。
“排程器跑起來了。”陳教授的聲音很平靜,但呂辰注意到他扶眼鏡框的手指微微頓了一下。
“接下來測試任務分發。”陳教授從帆布包裡拿出一張二維卡,插進一號機的讀卡機,“這是一個簡單的測試任務——計算斐波那契數列的前二十項。任務描述寫在卡片上,排程器會把它分發給負載最低的節點。”
他按下執行鍵。
顯示器上出現了新的輸出:
TASK SUBMITTED:ID= TYPE=FIBONACCI
SCHEDULER:DISPATCHING TO NODE 7 (LOAD=)
然後,幾秒鐘後,七號機的顯示器上亮起了計算結果,一行一行綠色的數字,從F1=1到F20=6765。
同時,一號機的顯示器上出現了:
TASK 0001 COMPLETED. RESULT STORED.
陳教授又提交了第二個、第三個、第四個任務,排程器分別把它們分給了節點3、節點11、節點14。所有任務都順利完成。
他轉過身,看著呂辰:“基本功能正常。接下來,你們可以把標準單元庫的資料導進去,然後在真機上跑一個真實的設計任務,看看排程器在大負載下的表現。”
呂辰點了點頭,心裡盤算著下一步的工作。
諸葛彪站在旁邊,雙臂交叉抱在胸前,盯著螢幕上的輸出看了好一會兒,忽然說:“陳教授,這個排程器,能同時跑多少個任務?”
陳教授想了想:“理論上是無限的。任務佇列用優先順序堆實現,記憶體裡最多快取一百個,超過一百個的會暫存在儲存櫃的磁碟上。每個任務提交的時候,排程器會估算它的計算量,當然,估算不準,你們用一段時間之後,可以根據實際執行時間反饋調整估算模型。”
錢蘭插了一句:“任務的優先順序怎麼定?”
陳教授翻開資料,找到一頁,指著一個表格:“預設是FIFO,先來先服務。但你們可以給任務打標籤,緊急任務可以設定高優先順序。排程器在處理佇列的時候,優先順序高的先出隊。”
他又補充道:“這個機制還在實驗階段。你們先用著,有甚麼問題隨時反饋。”
呂辰從筆記本上撕下一張紙,寫了一行字:“排程器雙機熱備待測試、優先順序機制待驗證。”
然後把紙貼在管理員桌旁邊的牆上。
陳教授看著那張紙條,笑了一下:“你倒是會抓重點。”
呂辰也笑了:“陳教授教得好。”
陳教授擺擺手,站起來走到中央儲存櫃前面,把手掌貼在櫃子的鐵皮外殼上,感受了一下溫度和震動。
櫃子裡的散熱風扇在均勻地運轉,發出低沉的嗡嗡聲。
他站了幾秒鐘,然後轉過身,看著呂辰。
“小呂,資料庫和排程器,我交給你們了。這是種子。你們要做的,是讓它長出來。”
他頓了頓,聲音低了一些:“理論組能做的,就是把地基打牢、把框架搭好。但真正讓這個系統活起來的,是裡面的資料,400多個標準單元,兩個工藝版本,每一個單元的版圖、模擬模型、測試向量。這些東西,計算機所的陳工寫不出,理論組寫不出,只有你們紅星所的人能填進去。”
“種子種下去,能不能發芽,看地,看水,看人。”
呂辰沉默了幾秒,然後點了點頭:“陳教授,我們不會讓種子爛在地裡的。”
陳教授沒再說甚麼,拍了拍他的肩膀。
他走到機房門口,回過頭,又看了一眼那16臺墨綠色的機櫃和三個鐵櫃子。
日光燈的光照在他的眼鏡片上,反射出一片白茫茫的光,看不清他的眼神。
然後他推門出去了。
走廊裡的熱浪湧進來,和機房的冷氣撞在一起,在地面上凝出一層薄薄的水霧。
呂辰站在機房門口,看著陳教授的背影消失在走廊盡頭。
帆布包空了,扁扁地搭在他肩上。
腳步聲越來越遠,最後被風扇的嗡嗡聲吞沒。
呂辰回到管理員桌前,看著螢幕上那個綠色的提示符:“DB>”
他敲了一個命令:DB> SHOW TABLES
螢幕上列出了三張表:CELLS、PROJECTS、TASKS。
CELLS是標準單元庫,空的。
PROJECTS是專案資訊,空的。
TASKS是任務記錄,空的。
三張空表,像三塊剛翻好的地,等著播種。
呂辰把那個命令記在筆記本上,合上本子,轉過身。
諸葛彪和錢蘭站在他身後,一個叼著煙,一個抱著筆記本,都看著他。
“明天開始,標準單元庫錄入。”呂辰說,“12臺機器錄入,四臺機器校驗,三班倒。先把最常用的50個閘電路,與非門、或非門、反相器、傳輸門,兩個工藝版本,一共一百條記錄,優先填進去。兩天之內,我要看到資料庫裡有資料。”
他又補了一句:“有了這一百個門,我們就可以開始設計儲存晶片了。”
諸葛彪把煙從嘴裡拿下來,彈了彈菸灰:“錄入格式呢?手冊裡那些座標資料,怎麼轉換成文字檔案?”
“今晚定。錢師姐,你帶人寫一個錄入模板。每個單元的版圖座標按‘圖層:起點X,起點Y,終點X,終點Y’的格式寫。模擬模型按‘引數名=引數值’的格式寫。測試向量按‘輸入A,輸入B,輸出Y’的格式寫。統一標準,方便匯入。”
錢蘭點頭,在本子上記下來。
“曾師兄,你負責排程器的日常監控。明天開始,讓系統連續跑72小時,記錄心跳、任務分發、任務回收的資料。任何異常都要記下來,反饋給陳工。”
曾祺應了一聲。
“周建國,你帶第一小隊的人,把機房的值班表排出來。三班倒,每班八小時,交接班要有記錄。誰錄入、誰校驗、誰複核,每一條資料都要有責任人。”
呂辰把任務一條一條地分配下去,筆記本上的字跡潦草但力道很重。
分配完的時候,已經快中午了。
陽光從機房的窗戶照進來,透過雙層玻璃,在墨綠色的機櫃上投下一片金黃。
16臺KJ-0A的顯示器都亮著,螢幕上顯示著“DB>”的提示符,安靜地等待著。
像16個沉默的農夫,等著播種。
呂辰站在機房中央,看著這一切。
鋤頭已經造好,能翻出甚麼樣的地,接下來就看怎麼挖了。