目前我正在為帶有 Cortex-M4 處理器的 STM32F4VE 撰寫一個輕量級的 RTOS。多個行程之間以回圈方式進行背景關系切換作業正常,但盡可能優化內核機制是我的一個愛好。TCB 堆疊在 SRAM 底部的保留區域中。
在每個背景關系切換我搜了下TCB是這樣的:
((pid 1) * TCB_Size) TCB_BASE_ADRESS。
如果 pid 等于任務數量,我將其重置為 0。這是通過 if 三元運算子而不是昂貴的模運算來完成的。
例如,當每 8ms 切換一次時,CPU 必須每次都進行乘法運算。我想知道在生成每個任務時預先計算這些 tcb 地址并將它們直接寫入記憶體是否會更有效。
第二種變體是每次背景關系切換訪問記憶體 2 次 - 獲取 tcb 的地址,獲取 tcb。否則會有一個“昂貴的”乘法。
哪個變體會更有效?如果沒有人有絕對的答案,我會重寫這個概念并做一個簡單的基準測驗。
謝謝!
uj5u.com熱心網友回復:
在每次背景關系切換時,我都會像這樣搜索下一個 TCB: ((pid 1) * TCB_Size) TCB_BASE_ADRESS 。
只需使用回圈鏈表;喜歡:
pointer_to_next_task_TCB = pointer_to_this_task_TCB->next;
switch_to_task(pointer_to_next_task_TCB);
...哪里pointer_to_this_task_TCB是全域變數(僅限單 CPU)或特定于 CPU 的變數;以及switch_to_task(pointer_to_next_task_TCB);確保pointer_to_this_task_TCB = pointer_to_next_task_TCB;作為任務切換的一部分(或立即之后)完成的地方。
請注意,當任務阻塞(睡眠,等待磁盤 IO,等待獲取互斥鎖,...)時,您需要將它們從鏈表中洗掉,以確保調度程式沒有給它們 CPU 時間,然后執行任務切換盡快(在任務的時間片結束之前不浪費 CPU 時間);并且當任務解除阻塞(時間延遲到期,資料從磁盤到達,...)時,需要將它們重新插入到鏈表中,以便調度程式再次給它們 CPU 時間,并且需要將它們插入到正確的位置(串列的當前末尾)以防止拒絕服務/CPU hogs(例如,任務故意阻塞極短的時間以不斷地放回串列的開頭并獲得一個全新的時間片,而其他任務則沒有CPU 時間)。
不要忘記,在正常情況下,大多數任務大部分時間都被阻塞(并且它們的 TCB 大部分時間都不在調度程式的鏈表上);并且該串列幾乎從不按 PID 順序排列。
例如; 如果有 100 個任務,其中 96 個任務被阻塞等待,那么調度程式的鏈表可能是“PID 9、PID 74、PID 31、PID 46,然后再回到 PID 9”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/404899.html
標籤:
