文章描述基于Rhealstone的系統(tǒng)實(shí)時性的測量基準(zhǔn)的框架--R-Rhealstone框架。
在嵌入式軟件設(shè)計(jì)和集成中,實(shí)時多任務(wù)操作系統(tǒng)的性能分析是至關(guān)重要的,它需要保證應(yīng)用的時間限制得到滿足,即是運(yùn)行時間不能超過應(yīng)用的時間限制。為了選擇滿足用于特定應(yīng)用的嵌入式系統(tǒng)的一個適當(dāng)?shù)牟僮飨到y(tǒng),我們需要對操作系統(tǒng)服務(wù)進(jìn)行分析。這些操作系統(tǒng)服務(wù)是由形成性能指標(biāo)的參數(shù)確定的,既定的性能指標(biāo)包括上下文切換時間、任務(wù)搶占時間、中斷延遲時間、信號量混洗時間、死鎖解除時間、信息傳輸延遲。
關(guān)于實(shí)時操作系統(tǒng)對性能指標(biāo)進(jìn)行分析,是為了選擇滿足用于特定應(yīng)用的嵌入式系統(tǒng)的最優(yōu)的操作系統(tǒng)。
Rhealstone
Rhealstone是系統(tǒng)實(shí)時性的測量基準(zhǔn)之一,Rhealstone性能基準(zhǔn)程序是實(shí)時系統(tǒng)的六個關(guān)鍵操作的時間量進(jìn)行操作,這六個關(guān)鍵操作是:上下文切換時間、任務(wù)搶占時間、中斷延遲時間、信號量混洗時間、死鎖解除時間、信息傳輸延遲。這六項(xiàng)操作作為Rhealstone的六個組件,每個組件被單獨(dú)測量。然后將經(jīng)驗(yàn)結(jié)果合并為單一的測量值,即是Rhealstone值。
測量Rhealstone值方式:
序號 | 說明 |
---|---|
方式 1 | 通用Rhealstone |
方式 2 | 每個組件應(yīng)用于具體應(yīng)用程序的特定Rhealstone |
Rhealstone性能基準(zhǔn)程的缺點(diǎn):
序號 | 說明 |
---|---|
缺點(diǎn) 1 | 測量的是平均時間,而不是最壞值 |
缺點(diǎn) 2 | 后的結(jié)論是加權(quán)平均值,沒有給出確定權(quán)值的依據(jù) |
R-Rhealstone框架
設(shè)計(jì)R-Rhealstone框架的目的:為了能讓對比的系統(tǒng)實(shí)時性的測量的一致性,必須保證同一個環(huán)境,解除差異性帶來測量干擾,所以R-Rhealstone框架提供了操作系統(tǒng)適配層,統(tǒng)一適配不同操作系統(tǒng)的各個接口,目的可以達(dá)到上層調(diào)用層次一致。
上下文切換時間
描述:
上下文切換時間也稱任務(wù)切換時間(task switching time),定義為系統(tǒng)在兩個獨(dú)立的、處于就緒態(tài)并且具有相同優(yōu)先級的任務(wù)之間切換所需要的時間。它包括三個部分,即保存當(dāng)前任務(wù)上下文的時間、調(diào)度程序選中新任務(wù)的時間和恢復(fù)新任務(wù)上下文的時間。切換所需的時間主要取決于保存任務(wù)上下文所用的數(shù)據(jù)結(jié)構(gòu)以及操作系統(tǒng)采用的調(diào)度算法的效率。產(chǎn)生任務(wù)切換的原因可以是資源可得,信號量的獲取等。任務(wù)切換是任一多任務(wù)系統(tǒng)中基本效率的測量點(diǎn),它是同步的,非搶占的,實(shí)時控制軟件實(shí)現(xiàn)了一種基于同等優(yōu)先級任務(wù)的時間片輪轉(zhuǎn)算法。影響任務(wù)切換的因素有:主機(jī)CPU的結(jié)構(gòu),指令集以及CPU特性。
任務(wù)切換過程增加了應(yīng)用程序的額外負(fù)荷。CPU的內(nèi)部寄存器越多,額外負(fù)荷就越重。任務(wù)切換所需要的時間取決于CPU有多少寄存器要入棧。實(shí)時內(nèi)核的性能不應(yīng)該以每秒鐘能做多少次任務(wù)切換來評價(jià),RTOS中通常是1微秒左右。
流程:
原理:創(chuàng)建兩個同等優(yōu)先級的任務(wù),兩個任務(wù)相互切換多次,最后求平均值。
注意:①需要減去多次切換的循環(huán)時間(loop_overhead);②需要減去主動讓CPU執(zhí)行時間(dir_overhead)
時間計(jì)算公式:
total_time:多次上下文切換總時間
loop_overhead:多次切換的循環(huán)時間
iterations:切換的次數(shù)
dir_overhead:調(diào)用讓出CPU接口的時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" staticfloatloop_overhead=0.0; staticfloatdir_overhead=0.0; staticfloattelapsed=0.0; staticuint32_tcount1,count2; staticrst_task_idrst_task1=NULL; staticrst_task_idrst_task2=NULL; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task2_attr={ .name="task2", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_task2_func(void*arg); staticvoidrst_task1_func(void*arg) { rst_task_create(&rst_task2,rst_task2_func,NULL,&rst_task2_attr); if(rst_task2==NULL) { RST_LOGE("RST:task2createfailed"); rst_task_delete(NULL); return; } /*Yieldprocessorsosecondtaskcanstartupandrun*/ rst_task_yield(); for(count1=0;count1
任務(wù)搶占時間
描述:
搶占時間即系統(tǒng)將控制權(quán)從低優(yōu)先級的任務(wù)轉(zhuǎn)移到高優(yōu)先級任務(wù)所花費(fèi)的時間。為了對任務(wù)進(jìn)行搶占,系統(tǒng)必須首先識別引起高優(yōu)先級任務(wù)就緒的事件,比較兩個任務(wù)的優(yōu)先級,最后進(jìn)行任務(wù)的切換,所以搶占時間中包括了任務(wù)切換時間。
它和任務(wù)切換有些類似,但是搶占時間通常花費(fèi)時間更長。這是因?yàn)閳?zhí)行中首先要確認(rèn)喚醒事件,并評估正在運(yùn)行的任務(wù)和請求運(yùn)行的任務(wù)的優(yōu)先級高低,然后才決定是否切換任務(wù)。實(shí)質(zhì)上,所有的多處理任務(wù)可以在執(zhí)行期間動態(tài)分配優(yōu)先級,所以,搶占時間也是衡量實(shí)時性能的重要指標(biāo)。
流程:
原理:創(chuàng)建兩個任務(wù),任務(wù)1優(yōu)先級比任務(wù)2優(yōu)先級低,兩個任務(wù)進(jìn)行搶占多次,最后求平均值。
注意:①需要減去多次任務(wù)搶占的循環(huán)時間(loop_overhead);②需要減去掛起任務(wù)所需要的時間(dir_overhead)
時間計(jì)算公式:
total_time:多次任務(wù)搶占總時間
loop_overhead:多次任務(wù)搶占的循環(huán)時間
iterations:任務(wù)搶占的次數(shù)
switch_overhead:掛起任務(wù)所需要的時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" staticfloatloop_overhead=0.0; staticfloatswitch_overhead=0.0; staticfloattelapsed=0.0; staticuint32_tcount; staticrst_task_idrst_task1=NULL; staticrst_task_idrst_task2=NULL; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-3, #else .priority=RST_TASK_HIGHEST_PRIORITY+3, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task2_attr={ .name="task2", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_task2_func(void*arg); staticvoidrst_task1_func(void*arg) { /*Startuptask2,getpreempted*/ rst_task_create(&rst_task2,rst_task2_func,NULL,&rst_task2_attr); if(rst_task2==NULL) { RST_LOGE("RST:task2createfailed"); rst_task_delete(NULL); return; } switch_overhead=rst_benchmark_time_read(); rst_benchmark_time_init(); /*Benchmarkcode*/ for(count=0;count
中斷延遲時間
描述:
中斷延遲時間是指從接收到中斷信號到操作系統(tǒng)做出響應(yīng),并完成進(jìn)入中斷服務(wù)例程所需要的時間。多任務(wù)操作系統(tǒng)中,中斷處理首先進(jìn)入一個中斷服務(wù)的總控程序,然后才進(jìn)入驅(qū)動程序的ISR。
中斷延遲時間=最大關(guān)中斷時間+硬件開始處理中斷到開始執(zhí)行中斷服務(wù)例程第一條指令之間的時間。
硬件開始處理中斷到開始執(zhí)行中斷服務(wù)例程的第一條指令之間的時間由硬件決定,所以,中斷延遲時間的長短主要取決于最大關(guān)中斷的時間。硬實(shí)時操作系統(tǒng)的關(guān)中斷時間通常是幾微秒,而Linux最壞可達(dá)幾毫秒。
流程:
原理:創(chuàng)建一個任務(wù),任務(wù)執(zhí)行主動觸發(fā)中斷,執(zhí)行完中斷服務(wù)程序返回,統(tǒng)計(jì)其時間。
注意:①需要減去讀取時間接口的耗時時間(timer_overhead);
時間計(jì)算公式:
isr_enter_time:多次任務(wù)搶占總時間
iterations:任務(wù)搶占的次數(shù)
timer_overhead:讀取時間接口的耗時時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" staticfloattimer_overhead=0.0; staticfloatisr_enter_time=0.0; staticrst_task_idrst_task1=NULL; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_LOWEST_PRIORITY+1, #else .priority=RST_TASK_LOWEST_PRIORITY-1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_isr_handler(void*param) { isr_enter_time=rst_benchmark_time_read(); } staticvoidrst_task1_func(void*arg) { rst_isr_install(RST_ISR_NUM,rst_isr_handler,NULL); /*Benchmarkcode*/ rst_benchmark_time_init(); /*goestoIsr_handler*/ rst_isr_trigger(RST_ISR_NUM); RST_PRINT_TIME( "R-Rhealstone:interruptlatencytime", isr_enter_time, 1,/*OnlyRhealstonethatisn'tanaverage*/ timer_overhead, 0 ); rst_task_delete(NULL); } rst_statusrst_interrupt_latency_init(void) { rst_task_create(&rst_task1,rst_task1_func,NULL,&rst_task1_attr); if(rst_task1==NULL) { RST_LOGE("RST:task1createfailed"); returnRST_ERROR; } rst_benchmark_time_init(); rst_benchmark_time_read(); rst_benchmark_time_init(); timer_overhead=rst_benchmark_time_read(); returnRST_OK; }
信號量混洗時間
描述:
信號量混洗時間(semaphore shuffling time),是指從一個任務(wù)釋放信號量到另一個等待該信號量的任務(wù)被激活的時間延遲。在RTOS中,通常有許多任務(wù)同時競爭某一共享資源,基于信號量的互斥訪問保證了任一時刻只有一個任務(wù)能夠訪問公共資源。信號量混洗時間反映了與互斥有關(guān)的時間開銷,因此也是衡量RTOS實(shí)時性能的一個重要指標(biāo)。
流程:
原理:創(chuàng)建一個信號量和兩個相同優(yōu)先級的任務(wù)。代碼需要執(zhí)行兩次,第一次信號量不介入調(diào)度,計(jì)算任務(wù)切換的時間,第二次多次循環(huán),信號量接入調(diào)度,信號量在兩個任務(wù)中ping-pong執(zhí)行,計(jì)算總時間。
注意:①需要減去任務(wù)切換的時間(switch_overhead);
時間計(jì)算公式:
telapsed:多次信號量混洗總時間
iterations:信號量混洗的次數(shù)
switch_overhead:切換的時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" staticfloatswitch_overhead=0.0; staticfloattelapsed=0.0; staticuint32_tcount=0; staticuint32_tsem_exe=1; staticrst_task_idrst_task1=NULL; staticrst_task_idrst_task2=NULL; staticrst_sem_idrst_sem=NULL; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task2_attr={ .name="task2", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_task2_func(void*arg); staticvoidrst_task1_func(void*arg) { /*Startuptask2,yieldsoitcanrun*/ rst_task_create(&rst_task2,rst_task2_func,NULL,&rst_task2_attr); if(rst_task2==NULL) { RST_LOGE("RST:task2createfailed"); rst_task_delete(NULL); return; } rst_task_yield(); /*Benchmarkcode*/ for(;count
死鎖解除時間
描述:
死鎖解除時間(deadlock breaking time),即系統(tǒng)解開處于死鎖狀態(tài)的多個任務(wù)所需花費(fèi)的時間。死鎖解除時間反映了RTOS解決死鎖的算法的效率。
流程:
原理:創(chuàng)建一個信號量和三個任務(wù),優(yōu)先級排序:任務(wù)1 < 任務(wù)2 < 任務(wù)3。代碼需要執(zhí)行兩次,第一次信號量不介入調(diào)度,計(jì)算任務(wù)3切換到任務(wù)2,任務(wù)2切換到任務(wù)1得時間(即從高優(yōu)先級切換到低優(yōu)先級得時間),第二次多次循環(huán),信號量接入調(diào)度,任務(wù)3死鎖,任務(wù)2喚醒任務(wù)1,任務(wù)1解除死鎖,通過統(tǒng)計(jì)多次,求平均值。
注意:①需要減去任務(wù)切換的時間(switch_overhead);
時間計(jì)算公式:
telapsed:多次死鎖解除總時間
iterations:死鎖解除的次數(shù)
switch_overhead:任務(wù)切換的時間
lock_overhead:調(diào)用信號量持有接口所需要得時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" staticfloatswitch_overhead=0.0; staticfloatlock_overhead=0.0; staticfloattelapsed=0.0; staticuint32_tcount=0; staticuint32_tsem_exe=1; staticrst_task_idrst_task1=NULL; staticrst_task_idrst_task2=NULL; staticrst_task_idrst_task3=NULL; staticrst_sem_idrst_sem=NULL; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task2_attr={ .name="task2", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-3, #else .priority=RST_TASK_HIGHEST_PRIORITY+3, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task3_attr={ .name="task3", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-5, #else .priority=RST_TASK_HIGHEST_PRIORITY+5, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_task1_func(void*arg) { /*AlltaskshavehadtimetostartuponceTA01isrunning*/ /*Benchmarkcode*/ rst_benchmark_time_init(); for(count=0;count
信息傳輸延遲
描述:
信息傳輸延遲(datagram throuShput time),指一個任務(wù)通過調(diào)用RTOS的消息隊(duì)列,把數(shù)據(jù)傳送到另一個任務(wù)去時,每秒可以傳送的字節(jié)數(shù)。
流程:
原理:創(chuàng)建一個消息隊(duì)列和兩個任務(wù),優(yōu)先級排序:任務(wù)1 < 任務(wù)2。任務(wù)1負(fù)責(zé)發(fā)送數(shù)據(jù),任務(wù)2負(fù)責(zé)接收數(shù)據(jù),執(zhí)行多次,求平均值
注意:①需要減去調(diào)用消息隊(duì)列接收函數(shù)的時間(receive_overhead);
時間計(jì)算公式:
telapsed:多次信息傳輸總時間
iterations:死鎖解除的次數(shù)
loop_overhead:多次循環(huán)的時間
receive_overhead:調(diào)用消息隊(duì)列接收函數(shù)的時間
代碼:
#include"rst.h" #include"rst_ipc.h" #include"rst_btime.h" #defineRST_QUEUE_BUFF_SIZE4 staticfloatloop_overhead=0.0; staticfloatreceive_overhead=0.0; staticfloattelapsed=0.0; staticuint32_tcount; staticrst_task_idrst_task1=NULL; staticrst_task_idrst_task2=NULL; staticrst_queue_idrst_queue=NULL; staticintqueue_buff[RST_QUEUE_BUFF_SIZE]={0}; staticrst_task_attrrst_task1_attr={ .name="task1", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-3, #else .priority=RST_TASK_HIGHEST_PRIORITY+3, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticrst_task_attrrst_task2_attr={ .name="task2", #ifRST_BIG_NUM_HIGH_PRIORITY .priority=RST_TASK_HIGHEST_PRIORITY-1, #else .priority=RST_TASK_HIGHEST_PRIORITY+1, #endif .stack_size=RST_TASK_STACK_SIZE, }; staticvoidrst_task2_func(void*arg); staticvoidrst_task1_func(void*arg) { /*Putamessageinthequeuesorecieveoverheadcanbefound.*/ rst_queue_send(rst_queue, (constvoid*)queue_buff, (uint32_t)sizeof(queue_buff), (rst_time_t)RST_WAIT_FOREVER); /*Startupsecondtask,getpreempted*/ rst_task_create(&rst_task2,rst_task2_func,NULL,&rst_task2_attr); if(rst_task2==NULL) { RST_LOGE("RST:task2createfailed"); rst_task_delete(NULL); return; } for(;count
RTOS對比結(jié)論
對比環(huán)境說明
項(xiàng) | 說明 |
---|---|
芯片 |
芯片型號:stm32f401 芯片架構(gòu):Cortex-M4 主頻:84 MHz |
開發(fā)環(huán)境 | KEIL 5.x |
工具鏈 | ARMCC |
對比結(jié)果說明
對比項(xiàng) | RT-Thread | LiteOS | FreeRTOS | TobudOS |
---|---|---|---|---|
上下文切換 | 2.594596 us | 6.739740 us | 1.049049 us | 2.343343 |
任務(wù)搶占 | 7.360721 us | 7.603206 us | 2.715431 us | 4.523046 us |
中斷延遲 | 2.000000 us | 1.000000 us | 1.000000 us | 1.000000 us |
信號量混洗 | 23.829000 us | 25.588000 us | 19.496000 us | 18.451000 us |
死鎖解除 | 18.108000 us | 18.074000 us | 21.522000 us | 31.606000 us |
信息傳輸延遲 | 7.749499 us | 7.390782 us | 7.298597 us | 3.446894 us |
總結(jié)
作者測試過程采用定時器計(jì)數(shù)器是1us,精度上有所欠缺,策略結(jié)果大致對比
中斷延時部分,RT-Thread的中斷是有框架的,而LiteOS和FreeRTOS直接使用STM32的HAL庫,時間差異在框架的耗時
FreeRTOS在本次的對比的優(yōu)勢比較明顯,除了死鎖解除稍微遜色一點(diǎn),其他的持平或由于RT-Thread和LiteOS
LiteOS在本次對比表現(xiàn)最差,尤其是上下文切換的耗時是RT-Thread和FreeRTOS的2~3倍。
開源鏈接
鏈接路徑:https://github.com/RiceChen0/r-rhealstone.git
說明:該框架目前已經(jīng)適配作為RT-Thread的軟件包,可以通過軟件包體驗(yàn)其功能
審核編輯 黃宇
-
嵌入式
+關(guān)注
關(guān)注
5087文章
19145瀏覽量
306136 -
框架
+關(guān)注
關(guān)注
0文章
403瀏覽量
17511 -
RTOS
+關(guān)注
關(guān)注
22文章
817瀏覽量
119720
發(fā)布評論請先 登錄
相關(guān)推薦
評論