リアルタイムタスクと非リアルタイムタスクの性能差を確認すべく、Raspbbery Piに矩形波を生成させ、ストレスをかけてみました。使用したコードは以下の通り。
#include#include #include #include #include #include #include #define MY_PRIORITY (49) /* we use 49 as the PRREMPT_RT use 50 as the priority of kernel tasklets and interrupt handler by default */#define MAX_SAFE_STACK (8*1024) /* The maximum stack size which is guaranteed safe to access without faulting */#define NSEC_PER_SEC (1000000000) /* The number of nsecs per sec. */void stack_prefault(void) { unsigned char dummy[MAX_SAFE_STACK]; memset(dummy, 0, MAX_SAFE_STACK); return;}int main(int argc, char* argv[]){ struct timespec t; struct sched_param param;// int interval = 500000000; /* 500ms*/ int interval = 50000; /* 50us*/ /* Declare ourself as a real time task */ param.sched_priority = MY_PRIORITY; if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror(""sched_setscheduler failed""); exit(-1); } /* Lock memory */ if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) { perror(""mlockall failed""); exit(-2); } /* Pre-fault our stack */ stack_prefault(); clock_gettime(CLOCK_MONOTONIC ,&t); /* start after one second */ t.tv_sec++; wiringPiSetup () ; pinMode (7, OUTPUT) ; while(1) { /* wait until next shot */ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); /* do the stuff */// printf(""hello\n""); digitalWrite (7, HIGH) ; /* calculate next shot */ t.tv_nsec += interval; while (t.tv_nsec >= NSEC_PER_SEC) { t.tv_nsec -= NSEC_PER_SEC; t.tv_sec++; } /* wait until next shot */ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); /* do the stuff */// printf(""good night\n""); digitalWrite (7, LOW) ; /* calculate next shot */ t.tv_nsec += interval; while (t.tv_nsec >= NSEC_PER_SEC) { t.tv_nsec -= NSEC_PER_SEC; t.tv_sec++; } }}
公式のサンプルにWiringPiでのピンのアップダウンを加えただけです。これがhigh_priorityの方。
param.sched_priority = MY_PRIORITY; if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror(""sched_setscheduler failed""); exit(-1); }
low_priorityはhigh_priorityの上記の優先度設定部分をコメントアウトしたものです。ストレスはstressコマンドでかけました。low_priorityは起動直後は良いのですが、stressで負荷をかけた途端ぐちゃぐちゃになります。一方high_priorityはそのまま。よく見るとstressをかけない状態でもhigh_priorityの方が波形が安定している様に見えます。デフォルトカーネルもconfig_preemptは入っているので、それとの比較をすべきなのですが、手元に環境が無いのでそれはまたいつか。 “””