本計畫研究的中心概念為異質雙核 心平台上的動態分工。如之前所述,動態 精細分工是以同時考量整個平台的各異質 核心的即時計算狀態為排程的依據,以期 達到最高的效能。Fig. 11是我們設計的系 統架構。原本利用 eCos 為 kernel 的系統架 構包含有:應用程式 application(APP),應 用程式可以透過 eCos kernel 和 HAL 利用 底層平台的硬體,如 GPP 和 DSP。其中 eCos kernel 最重要的元件是 MLQ
scheduler。在 eCos kernel 中加入 Dispatcher、Service Registrar、和 core service table。應用程式經過 Scheduler API 可以和 kernel 或 Service Registrar
括註冊 dual-core services,和下達執行 services 的命令。這些新加入的單元,即是 scheduler 的核心。以下,我們把這個異質 雙核心動態分工排程器稱做
Heterogeneous Multi-Processor (HMP) scheduler。
APP
HHMP Scheduler API
Service Registrar
core service table
eCos kernel
HAL interface/HAL API
GPP DSP
Dispatcher
MLQ
Fig. 11. 系統架構
接下來會逐一介紹 scheduler 的每 一個元件、它們各別的功能、以及運作方 式。scheduler 的每個元件溝通都是雙向的 動作,例如 Dispatcher 可能會向 Service
Registrar 索取特定 service 的執行指標,
Service Registrar 就會回覆之。圖中 eCos kernel 會透過一組 API 和 DSP 溝通,這一 組 API 是同一研究團隊成員提供的介面,
因為它不是本研究的重點,僅在最後做簡 單介紹。
4.1 Scheduler API
這個介面提供 scheduler 使用上的 便利性。Scheduler API 是新的 system call,它的目標就是令使用者在移植單核心 的應用程式為異質雙核心應用程式時,只 需做最小的修改,便能使用 scheduler。因 此 Scheduler Interface 提供兩類三個系統 呼叫的程式,它們是註冊和執行這兩類:
HMP_register_service()
HMP_invoke_service()
HMP_remove_service() HMP_register_service()和
HMP_remove_service()歸屬於註冊類。它 們扮演的功能是向 kernel 註冊某項 service 為 dual-core service 或是移除之。一旦註冊 了某項 service 為 dual-core service,之後使 用這個 service 時,就會被引入 HMP scheduler,由 GPP 或由 DSP 負責執行都有 可能。使用 service 的方法,在註冊後,
HMP Scheduler API 會給使用者一個 ID。
使用 service 就要呼叫
HMP_invoke_service(),填入 ID 指定註冊 的 service 和填入原 service 的參數。
HMP_invoke_service()被設計為可容納不 同數量參數的介面,因此各種數量參數皆 可以處理。舉一個簡單的例子,在之後的 實驗裡,測試的應用程式為 H. 263
decoder。圖 11 中 Idct 是 decoder 其中一個 程式,接受的參數是一個 short。欲使用 HMP scheduler 只需把程式改為圖 12 的寫 法。
void idct(short *block) { … }
void main() { …
idct(block);
… }
Fig. 12. 一般單核心 idct 函數的使用方法 Idct 程式不必做任何修改。在主程 式中呼叫 idct 之前,先用
HMP_register_service(idct_image)註冊取 得 id。之後要使用 idct 就改呼叫 idct(block) 為呼叫 HMP_invoke_service(id, block)。id 是向 kernel 取得的資料,而 block 是原本 主程式的指標資料。全部就只要做到這些 修改,應用程式幾乎看不到有單核心雙核 心程式的不同,移植的便利性非常大。
void idct(short *data) { … }
void main() {
int id;
…
id = HMPHMP_register_service(idct_image);
…
HMPHMP_invoke_service(id, block);
… }
Fig. 13. HMP scheduler 下 idct 使用方法 OMAP 5912 是屬於雙核心的晶 片,因此 HMP Scheduler 在執行排程工作 之外,要負責 DSP 的啟動。當然 DSP 的 啟動可以在 booting 時完成,考量並非每 一種應用程式都需要用到 DSP,只在 HMP Scheduler 被啟動時才自動啟動 DSP,以減 少 booting 的 overhead。另外有一個做法也 是可以實行的,那就是將 DSP 啟動轉換成 bootstrap (Redboot)的指令,欲使用 HMP Scheduler 時,要先下該指令啟動 DSP,再 執行應用程式。
4.2 Service Registrar 和 Core Service Table
應用程式向 Service Registrar 註冊 service,Service Registrar 收到 service 的資
訊如下:
Service function pointer
Service DSP binary image pointer 得到所需資訊的 Service Registrar 開始進行註冊動作。首先在 core service table 內紀錄 function pointer。接著透過 DSP API 將 DSP binary image 傳入 DSP internal RAM,完成之後向 DSP 註冊該 service,得到 DSP 回傳的 service DSP ID。
在 core service table 紀錄此 ID。之後都用 此 ID 向 DSP 做指定 service 的動作。未來 function pointer 會改成 ARM 的 image。
ARM 的 image 和 DSP 的 image 會包成一 個資料結構。
完成上述程序的 Service Registrar 會產生一個 service kernel ID,回傳給應用 程式。Service kernel ID 和 service DSP ID 是不同的。前者是應用程式和 kernel 互動 時,用來指明 service 的依據。應用程式要 執行 service 時,若 Dispatcher 判斷該 service 為 GPP 執行,kernel 會根據 service kernel ID 到 core service table 找到正確的 function pointer,由 GPP 端執行 service;
若 service 被判斷為 DSP 執行,kernel 依 service kernel ID 在 core service table 內找 對應的 service DSP ID。在通知 DSP 執行 某個 service 時,一併傳入 service DSP ID,
如此一來 DSP 便了解該執行哪一個 service。所以 service kernel ID 和 service DSP ID 是完全不相同。
Service Register 另外一項功能為移 除 service。接受移除指令的 Service Register 會自 core service table 中移除紀 錄。並將 service image 從 DSP 內移除。
4.3 Dispatcher
Dispatcher 負責在應用程式要求執 行 dual-core service 之後,判斷由哪一顆 處理器來執行會得到最短的執行時間,進 而決定由哪一顆處理器執行。判斷由 GPP 執行,就直接將 service 交給
MLQscheduler,依原本 eCos kernel 的路徑 執行,但結束時會有些許改變;或是由 DSP 執行該 service。Dispatcher 的架構圖如下:
Task Dispatcher Cost Calculator
Dispatcher
GPP loading table
DSP loading table
Task Terminator HMP Scheduler Interface
MLQ / API to DSP
Fig. 14. Dispatcher 架構圖
Dispatcher 是由三大單元組成,它 們分別是 Task Dispatcher、Task
Terminator、和 loading tables。執行 dual-core service 的資訊經 HMP Scheduler Interface 傳入 Dispatcher。一旦 Task Dispatcher 接收到資訊,會喚醒 Cost Calculator。Cost Calculator 開始計算 cost value,接著便回傳 Cost value 給 Task Dispatcher。Task Dispatcher 就以 cost value 判定由哪一處理器執行 service。Task Dispatcher 判定 service 的執行處理器,在 屬於該處理器的 loading table 新增 service loading 資料。只要 service 執行完畢,就 由 Task Terminator 來結束整個程序,包括 通知應用程式 service 執行完成,和自處理 器的 loading table 移除紀錄。由 loading table 的觀點來看,其 producer 是 Task Dispatcher,而 Task Terminator 為
consumer。此外,當 service 必須對大量資 料做運算使用到 pointer,而此 service 為被 決定為 DSP 執行時,Dispatcher 得負責 DSP 可以得到整筆資料,之後有段落會專 門介紹 Dispatcher 如何令 DSP 得到完整資 料的實作方式。
4.4 Task Dispatcher
Task Dispatcher 得自應用程式的 service ID 是 service kernel ID。Task
Dispatcher 的工作主要是依處理器的 loading 狀態,分配 service 給某一顆處理 器負責執行,我們所使用的動態排程方 式,基本上是根據過去的執行狀態來預測 何者未來的 loading 比較低,便將工作交由 該處理器執行。Task Dispatcher 會從 Cost Calculator 得到被呼叫的 service 在不同處 理器所需的執行時間的估測,分別記錄在 time_ARM_prediction 和
time_DSP_prediction 這兩個變數中。此動 態排程的判斷方法是將估測出的時間相 比,來決定誰該執行該工作:
time_ARM_prediction >
time_DSP_prediction: service 判定給 DSP 執行。
time_ARM_prediction <
time_DSP_prediction: service 判定給 ARM 執行。
time_ARM_prediction = time_DSP_prediction: service 判定給 DSP 執行。
在相等的情況下,service 會由 DSP 負責執行。其原因在於本平台系統專為處 理多媒體資料而設計,dual-core service 都 是數位訊號處理的形式,在 DSP 和 ARM 的速度和耗電力比較,和忽略雙核心溝通 的 overhead 的前提之下,DSP 更適合擔任 執行角色,因此判定由 DSP 執行。
在 Cost Calculator 的部份,是利用 指數平均數(exponential average)的方法來 預測 service 的執行時間。依公式:
n nn t T
T 1 1
1
Tn
: 預估這一次執行時間。
tn
: 上一次實際執行時間。
Tn
: 上一次預估的執行時間。
: 比例常數,常用 0.5;這裡使用 0.7 加重實際時間的比重。
每一類 service 執行時間的預測都
是獨立的,換言之,每一類 service 都有專 ARM 又快一點,Cost Calculator 計算的結 果是 ARM 較小,該 idct 就由 ARM 來執 行;如果又回到 DSP 快的情況下,Cost Calculator 計算的值 DSP 會較小,變由 DSP 來執行 idct。實作過程中,發現一種特殊 生時,Cost Calculator 會自動將此次的預測 值除以特定值。以便讓下一次的預測值縮 定之後,Task Dispatcher 要在對應處理器 loading table 增加 service 紀錄,和更新處 理器全部執行時間。接著交付 service 給處 理器執行。
4.5 Task Terminator
Task Dispatcher 和 Task Terminator 在系統中的角色是相反的。它接受 ARM 或是 DSP 結束 service 執行的訊息,自 service loading table 移除 service 紀錄,和 更新處理器全部執行時間。下一步再通知 應用程式”己經完成 service”。
4.6 Loading Tables
Loading table 用來紀錄各處理器的 loading 狀態,和各處理器上執行的 services。意義上 ARM(DSP) service table 是紀錄 service 種類,而 ARM(DSP) loading table 是紀錄每一個處理器上正在執行的 service。換句話說,同一種 service 種類在 ARM(DSP) service table 只有一筆資料,但 在 ARM(DSP) loading table 上,只要應用 程式對同一種 service 要求執行幾次,同一
Fig. 15. Loading table
Loading table 分為 header node 和
common node。Header node 紀錄其負責處 理器上所有執行中 task 的數目(task
number),和所有的執行時間(total time)。
未來我們會增加不同 cost function 考慮的 因素,概括說來是不同種類的核心 loading 狀態,如電力消耗。在 header node 預留一 些欄位可以用來記錄新增的 loading 狀 態。每一個 common node 代表一個執行中 的 service,紀錄著在 loading table 上的位 置(index)、執行時間(execution time)、和名 稱(service name)。這是一個 double
direction linked list 資料結構,有鑑於不同 的 service 有不同的執行時間,亦即 service 加入 table 的順序不會和離開 table 的順序 相同,使用 linked list 處理這個特性。
4.7 雙核心溝通方法
使用 mailbox 和 shared memory 的組 合。OHMP 5912 上有四組 mailbox,其中 兩組為 ARM to DSP,另兩組為 DSP to ARM。顧名思義,ARM to DSP 為 ARM 發給 DSP 的 mailbox,DSP to ARM 是 DSP 發給 ARM 的 mailbox。每組 mailbox 上有 兩個 16 位元 register,一個設定為 command register,另一個為 data register。在 ARM to DSP mailbox 上,ARM 有完全的讀寫權 利,DSP 只有讀取的權限;反之亦然。ARM 填完第二個 register 時,硬體會自動設定一 個 flag,因此 DSP 會有 interrupt 產生。DSP 開始讀取兩個 register 的資料,讀完第二個 register 之後,flag 會再由硬體設回 0,表 示 DSP 讀取完畢。利用 mailbox 傳遞做為 雙核心 service 執行的開端。
設計三種 ARM to DSP mailbox action command,如下:
Register: 註冊 service。
Invoke: 執行 service。
Remove:移除 service。
以及 DSP to ARM mailbox action command,是 ARM to DSP 的回應指令如 下:
Return register: 完成 service 註冊。
Return invoke: 完成 service 執行。
Return remove: 完成 service 移除。
ARM 發 register mailbox action command 註冊 service 之前,ARM 利用 DSP API 把 service image 放入 DSP space internal RAM。完成註冊動作,DSP 會回 return register mailbox action command,並 利用 data register 儲存 service DSP ID。再 由 Service Registrar 存入 DSP service table。相同的運做模式,但功能相反是 remove。
最後一種指令為 invoke 指令。ARM 在 command register 填入 invoke 指令,data register 填入自 DSP service table 取得的 service DSP ID。依此行為 DSP 便會開始 執行要求的 service。著眼於 mailbox 只提 供兩個 16 位元的 register,沒有辦法利用 mailbox 傳入其它參數或資料。為了解決
最後一種指令為 invoke 指令。ARM 在 command register 填入 invoke 指令,data register 填入自 DSP service table 取得的 service DSP ID。依此行為 DSP 便會開始 執行要求的 service。著眼於 mailbox 只提 供兩個 16 位元的 register,沒有辦法利用 mailbox 傳入其它參數或資料。為了解決