• 沒有找到結果。

Lock Object Accessing Controller

在文檔中 多執行緒Java處理器設計 (頁 50-62)

第三章 Multicore Multithreading Java 處理器架構

3.4. Data Coherence Controller

3.4.3. Lock Object Accessing Controller

圖 31 說明 Lock Object Accessing Controller 的設計。在 Java 程式執行期間,

lockObj_curCount 儲存目前被某些 threads 占用的 lock object 個數,當多核心 JAIP 處理 器執行指令時,如果有 2 個以上 threads 想要取得某個 lock object 並且目前沒有被其他 thread 占用,則第一個取得此權限的 thread 便會累加 lockObj_curCount 的值;當某個 thread 釋放該 lock object 且同時不存在相關 waiting threads 時遞減 lockObj_curCount 的值,其 餘狀況皆不更改 lockObj_curCount 的數值。

41

Lock Object Accessing Controller List Accessing Controller

DOA DOBDIA DIB

lockObj_

Lock Object Table

圖 31 The block diagram of Lock Object Accessing Controller

Waiting Thread Table 與 Lock Object Table 分別存放目前所有 waiting threads 與所有 被占用的 lock objects 相關資訊,當執行 Java 程式時,這 2 個 tables 會用到多少 entries 取決於其應用程式複雜度,如果這些資訊全部使用 register 儲存,雖然可以加快查詢速 度但是很容易使電路資源使用量過大。在此我們以一個 dual-port on-chip memory 實作 Waiting Thread Table 與 Lock Object Table,當 JAIP2DCC_cmd = 01 或 10,LOAC 可藉由 32-bit input port (DIA、DIB)與 32-bit output port (DOA、DOB)同時讀寫 Waiting Thread Table 與 Lock Object Table 的 entry,這 2 種 list entry 格式如圖 32所示,valid bit 代表目 前這個 entry 是否已被使用,其預設值為 0;next node address 為一個 7-bit address 指向 另一個 waiting thread entry,所有等待同一個 lock object 的 waiting threads 在 Waiting Thread Table 內部將形成一條 singly linked list、每一個 lock object entry 的 next node address 欄位將會指向 Waiting Thread Table 內部某條 linked list 的 head node、在此 head node 指的是擁有 lock 權限的 thread (lock 擁有者)其 ID number,在我們的設計中 Waiting Thread Table 內部每一條 linked list 的 tail node 的 next node address 欄位其值為 0x7F 代表 為預設值 NULL;counter 欄位代表目前 lock 擁有者重複取得幾次 lock object,當一個

42

waiting thread entry 的 valid bit = 0,此時該 counter 欄位為預設值 0;valid bit = 1 時,該

Next node Address [6 : 0]

Valid bit [31]

Object reference address [30 : 7]

Next node Address [6 : 0]

(a)

(b)

圖 32 The format of (a) waiting thread entry and (b) lock object entry

以圖 33為例,Lock Object Table 第 1 個 entry 儲存 Object L0 的參考位置,其 next node address 欄位指向 Waiting Thread Table 第 6 個 entry,這表示 Waiting Thread Table 內部存 在一條與 Object L0 有關的 linked list,該 list 的 head node 在第 6 個 entry,其 core ID = 10 與 thread ID = 0000000 代表目前 lock 擁有者的資訊,第 6 個 entry 的 next node address 欄等於二進位數值 0000000 將指向第 1 個 entry;Waiting Thread Table 的第 1 個 entry 其 core ID = 01 以及 thread ID = 0000100 代表目前 lock 擁有者釋放 lock 之後,會將 lock 權 限轉交到這個 thread,Object L0 在 Waiting Thread Table 內部從 head node 到 tail node 拜 訪順序分別是第 6、第 1、第 5 個 entry,並且整個 linked list 長度為 3。Lock Object Table 第 4 個 entry 儲存 Object L2 的參考位置,其 next node address 欄位指向 Waiting Thread Table 第 7 個 entry,而第 7 個 entry 的 core ID = 00、thread ID = 0000001、counter = 000011,

表示該 thread 成功取得 Object L2 的 lock 之後又重複取得 2 次 lock object L2。

使用 on-chip memory 的設計再配合圖 32 定義的資料格式,我們可以完整地紀錄 waiting threads 與 lock objects 資訊並且用少數的電路資源實作 LOAC。

43

圖 33 waiting thread entry 與 lock object entry 與關係圖

我們以圖 9 與圖 10 舉例說明 LOAC 如何維護 Waiting Thread Table、Lock Object Table 以及其他內部 registers,假設 thread t1 從 JAIP A 處理器呼叫 method B3,此時藉由 這個 JAIP 處理器發送 request signal 到 Data coherence Controller 請求取得或釋放 class B 底下的 lock object L0,JAIP A 的 Arbiter_Info 包含 L0 的參考位置與 t1 的 ID 資訊、LOAC 被啟動並且開始執行工作,以下幾種情況分別說明 LOAC 不同的執行流程。

Case A:當 t1 要請求取得 L0,arbitor_cmd_msg 的 command ID 欄位為 01,則 mutex_state

從 IDLE 轉成 WAIT_FOR_RES,所有內部 registers 皆被歸零。此時 LOAC 以一個內部 counter 作為 Waiting Thread Table (ADDRB,如圖 31) 與 Lock Object Table (ADDRA)索 引位置,從第 1 個 entry 開始,每個 clock 往下一個 entry 同步查詢 Lock Object Table 與 Waiting Thread Table(圖 34)。如果讀取到的 lock object entry 其 valid bit = 1 (圖 34的 E0[31]=1 為 true) 則累加 numLock_checked 表示已經檢查過這筆資料,否則目前 lock object entry 其 valid bit = 0,內部暫存器 nxtEmpty_LockObjLst 被用來記錄目前 lock object entry 對應的索引位置(ADDRA)。

44

Read Lock object entry E0 (DOA)

Read waiting thread entry E1 (DOB)

R0 = R0 + 1

R5 = 1 R6 = 1

R7= 1 Mutex = WAIT_FOR_RES

R2 = ADDRA

每個代號皆表示 Lock Object Accessing Controller 內部暫存器名稱,詳見圖 31 L0 : reference address of Object L0 T1 : thread information (core ID, thread ID) R0 = numLock_checked R5 = lock_obj_match_flag

R1 = lockObj_curCount R6 = lock_obj_free_flag R2 = nxtEmpty_LockObjLst R7 = find_empty_waitTHlist R3 = nxtEmpty_WaitLst R8 = search_waitLst_flag

R4 = lockOwner R9 = the_owner_acq_again

圖 34 LOAC 內部逐一比對 lock object 流程圖

當目前讀取到的 lock object entry 其 valid bit = 1,接著比對 lock object entry 的 Object reference address 欄位與 L0 的參考位置是否相同,如果相同則 lock_obj_match_flag 等於

45

1,最後比對 numLock_checked 與 lockObj_curCount。同時如果讀取到的 waiting thread entry 其 valid bit = 0 , 這 表 示 目 前 此 waiting thread entry 沒 有 被 使 用 , 則 find_empty_waitTHlist 等於 1 且利用內部 register nxtEmptyWaitLst 記錄目前 waiting thread entry 對應的索引位置。此時會遇到 2 種情況:

R7 = 1 R6 = 1

J1

Yes No

Yes

No

• Set information for lock object entry referred by R2

• Set information for waiting thread entry referred by R3

monEn_free_cmplt = 1 , generate response message J3

圖 35 LOAC 內部成功取得 lock object 之流程圖 J1、J3 表示流程連接點,請參考圖 34 Case A-1:。

如果 Lock Object Table 內沒有儲存 L0 參考位置,這表示 lock_obj_match_flag = 0 而且 numLock_checked = lockObj_curCount,t1 成功取得 L0,則內部訊號 lock_obj_free_flag 等於 1,當 find_empty_waitTHlist 等於 1 與 lock_obj_free_flag 等於 1 皆成立時期流程如 圖 35,LOAC 以 nxtEmpty_LockObjLst 作為 Lock Object Table 的索引位置,寫入 L0 的 參考位置與 nxtEmpty_WaitLst 的值,並且 valid bit 改成 1;同時以 nxtEmpty_WaitLst 作 為 Waiting Thread Table 的索引位置,寫入 thread t1 的 core ID、thread ID(圖 36)。當 mutex_state = GEN_RES_MSG,LOAC 累加 lockObj_curCount 的值,並且由 Response Controller 產 生 回 應 訊 號 到 DCC2JAIP_response_msg , DCC2JAIP_response_msg 的 Response status 為 100,代表 t1 已成功取得 L0。

46

圖 36 範例:在 Waiting Thread Table 產生一條 Object L0 的 linked list N0

Case A-2:

如果 Lock Object Table 內儲存 L0 參考位置,這表示 L0 可能已先被其他 thread 取得權限 (e.g. thread t2) ,lock_obj_match_flag = 1,此時 LOAC 內部 register lockOwner 會暫存 DOA 的 next node address 欄位,它代表一個指向 Waiting Thread Table 內與 L0 相關的 linked list (以下簡稱 N0),且 N0 的 head node 儲存 L0 的擁有者的 thread 資訊。當 find_empty_waitTHlist 與 lock_obj_match_flag 皆為 1,此時再觸發另一個內部信號 search_waitLst_flag 等於 1 (圖 37,R8 = 1),LOAC 開始在 N0 內查詢 lock 擁有者的 thread ID 與 core ID,首先以 register lockOwner 當作 Waiting Thread Table 的索引位置,抓出 N0 的 head node,如果目前指向的 waiting thread entry (DOB)的 core ID 與 thread ID 欄位 等於 t1 的 core ID 與 thread ID (圖 37 的 E1[30:22] = t1 為 true),則內部信號 the_owner_acq_again 等於 1,否則等於 0,根據 the_owner_acq_again 的值,可以再細分 下列 2 種情況:

47

• R8= 1

• Set information for waiting thread entry referred by R3 J2

Read waiting thread entry E1

(DOB)

• R9= 1

• E1[21:16] = E1[21:16] + 1

monEn_match_cmplt = 1 , generate response message Yes

Read waiting thread entry E1

(DOB)

E1[30:22] = T1

No

圖 37 查詢 Waiting Thread Table 內特定 lock object 的 linked list J2、J3 表示流程連接點,請參考圖 34

Case A-2-1:the_owner_acq_again = 0。

此時可以確定 L0 被其他 threads 占用(如圖 38),LOAC 必須在 Waiting Thread Table 內 分配一個未使用的 entry 儲存 t1 的 core ID 與 thread ID,並且將這個 entry 加入到 linked list N0 末端,其查詢流程如圖 37。為了執行以上步驟,首先 LOAC 必須從 N0 中抓出目前 tail node 的索引位置並修改其 next node address 欄位,上一段提到 LOAC 內部 register nxtEmpty_WaitLst 數值在 search_waitLst_flag 等於 1 之前就已經先準備好,也提到 search_waitLst_flag 等於 1 時表示 LOAC 開始依序拜訪 N0 的每一個 node,LOAC 在每 個 clock 開始,參考 DOB 的 next node address 欄位且檢查其數值是否為 NULL 或者指向 下一個 waiting thread entry,如果不是 NULL 則以此 next node address 欄位當作 Waiting Thread Table 的索引位置,同樣地在 N0 拜訪下一個 node,依此類推;如果發現目前拜

48

訪的 entry 其 next node address 欄位是 NULL,此時表示已找到 N0 的 tail node,

monEn_match_cmplt = 1、LOAC 必須將 nxtEmpty_WaitLst 的值寫到 tail node 的 next node address 欄位,同時將 nxtEmpty_WaitLst 的值當作 Waiting Thread Table 的輸入索引位置,

儲存 t1 的 core ID 與 thread ID,注意 nxtEmpty_WaitLst 指向的 entry 其 next node address 數值為 0x7F,在 N0 內新增一個 node 紀錄 waiting thread 的工作就此完成。最後 LOAC 回傳訊號到 Mutex Controller 更改狀態,產生回應訊號輸出到 DCC2JAIP_response_msg,

其 Response status 為 101,代表 t1 未成功取得 L0。

圖 38 範例:在 linked list N0 內新增一個 tail node

Case A-2-2:the_owner_acq_again = 1

此時可以確定先前 t1 已取得 L0 並且執行重複取得的工作(如圖 37 的判斷條件 E1[30:22]=T1),則 LOAC 只需要將 lockOwner 的值當作 Waiting Thread Table 索引位置,

累加 N0 的 head node 的 counter 欄位。最後 monEn_match_cmplt 等於 1,LOAC 回傳訊 號到 Mutex Controller 產生回應訊號到 DCC2JAIP_response_msg,其 Response status 為 100 代表 t1 成功地重複取得 L0。

Case B:假設 thread t2 要釋放 L0 並且 thread t1 正在等待 L0,則 arbitor_cmd_msg 的

49

command ID 欄位為 10,且 mutex_state 從 IDLE 轉成 WAIT_FOR_RES,此時 LOAC 查 詢 Lock Object Table 的流程與圖 34相同,但是不需要到 Waiting Thread Table 查詢未使 用 的 entry, LOAC 一 定 可 以 找 到 L0 在 Lock Object Table 對 應 的 entry ( 意 即 lock_obj_match_flag 必定為 1),因此當 lock_obj_match_flag = 1,則 search_waitLst_flag = 1,此時 ADDRA 指向 Lock Object Table 內 L0 的 entry,因此將 ADDRA 的數值暫時記 錄下來,同時開始搜尋 linked list N0 (如圖 39),由於先前每個 thread 取得 lock object 時 LOAC 已經維護各個 lock object 在 Waiting Thread Table 內對應的 linked list,所以在此我 們只需要讀取 N0 的 head node,檢查 next node address 是否為 NULL,以決定是否把 L0 轉移給其他 thread。首先以 register lockOwner 當作 Waiting Thread Table 的索引位置,讀 取 N0 的 head node,接著檢查 LOAC 取的 waiting thread entry (DOB)的 next node address 欄位是否等於 NULL (如圖 39的 E1[6:0]=0x7F 是否為 true)、以及 counter 欄位是否大於 1 (如圖 39的 E1[21:16]>1 是否為 true)。因此可分成以下 3 種情況:

J1

monEx_cmplt = 1 , generate response message

• Keep ADDRA unchanged

• R8= 1

• ADDRB = R4

• Read waiting thread entry E1 (DOB)

• Read Lock object entry E0 (DOA)

E1 [6:0] = 0x7F E1[21:16] > 1

No

• R9= 1

• E1[21:16] = E1[21:16] - 1 Yes

No

• Set default value for E1

• E0[6::0] = E1[6:0]

• Set default value for E1, E0

Yes

圖 39 lock 擁有者釋放 lock object 流程圖,J1 表示流程連接點,請參考圖 34 50

Case B-1:

waiting thread entry (thread t2)的 counter 欄位大於 1,此時 the_owner_acq_again 等於 1 表 示先前 t2 重複取得 L0,我們只需要將 waiting thread entry (t2)的 counter 欄位值遞減一個 單位即可,t2 仍然保持 L0 的權限。當 mutex_state = GEN_RES_MSG,產生回應訊號到 DCC2JAIP_response_msg,其 Response status 為 111,代表 t2 已完成釋放 L0 並且不作任 何權限轉移。

Case B-2:

waiting thread entry (thread t2)的 counter 欄位等於 1 並且 next node address 指向下一個 waiting thread entry(如圖 40的 thread t1),這表示還有其他 thread 正在等待取得 L0,所 以把 next node address 值寫到目前讀取的 lock object entry (L0)的 next node address 欄位 使 lock object entry 直接指向 t1 的 waiting thread entry,最後把目前讀取的 waiting thread entry 改回預設值。

Case B-3:

waiting thread entry (t2)的 counter 欄位等於 1 並且 next node address 等於 NULL (如圖 41),這表示當下沒有其他 waiting threads 正在等待取得 L0,此時 N0 僅剩下 2 個 nodes:

一個 lock object entry 用來儲存 L0 的資訊,以及另一個 waiting thread entry 儲存 T1 的資 訊,所以只需要將這 2 個 entries 還原預設值。

圖 40 範例:在 Waiting Thread Table 的 linked list N0 內移除 head node 51

圖 41 範例:在 Waiting Thread Table 移除 Object L0 與 thread t2

52

在文檔中 多執行緒Java處理器設計 (頁 50-62)