2015. 2. 24.

Xenomai의 성능비교

 Xenomai는 리눅스에서 실시간 처리가 보장되도록 하는 역할을 하게 된다.
이번에는 Xenomai에서 제공하는 예제인 trival-periodic과 리눅스 제공 함수인 CLOCK_gettime()을 이용한 예제를 가지고 비교를 해보겠다.


<< trivial-periodic.c 예제 >>

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>

#include <native/task.h>
#include <native/timer.h>

RT_TASK demo_task;

/* NOTE: error handling omitted. */

void demo(void *arg)
{
RTIME now, previous; //RTIME 변수 선언

/*
* Arguments: &task (NULL=self),
*            start time,
*            period (here: 1 s)
*/
rt_task_set_periodic(NULL, TM_NOW, 1000000000); //1초짜리 주기를 갖는 테스크 set
previous = rt_timer_read(); //현재 시간 저장

while (1) {
rt_task_wait_period(NULL); //한 주기가 끝날 때 까지 기다림
now = rt_timer_read(); //현재 시간 저장

/*
* NOTE: printf may have unexpected impact on the timing of
*       your program. It is used here in the critical loop
*       only for demonstration purposes.
*/
rt_printf("Time since last turn: %ld.%06ld ms\n",
      (long)(now - previous) / 1000000,
      (long)(now - previous) % 1000000); //시간 차이 출력

      previous = now; //'현재' -> '과거'로 업데이트
}
}

void catch_signal(int sig)
{
}

int main(int argc, char* argv[])
{
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);

/* Avoids memory swapping for this program */
mlockall(MCL_CURRENT|MCL_FUTURE); //메모리 lock

rt_print_auto_init(1);

/*
* Arguments: &task,
*            name,
*            stack size (0=default),
*            priority,
*            mode (FPU, start suspended, ...)
*/
rt_task_create(&demo_task, "trivial", 0, 99, 0); //위에서 만든 테스크로 테스크 생성

/*
* Arguments: &task,
*            task function,
*            function argument
*/
rt_task_start(&demo_task, &demo, NULL); //테스크 시작

pause();

rt_task_delete(&demo_task);

return 0;
}

- 결과 - 









<< gettime.c 예제 >>

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

#define BILLION 1000000000L

int loclapid(void){
static int a[9] = {0};
return a[0];
}

main (int argc, char **argv)
{
while(1)
{
uint64_t diff;
struct timespec start, end;
int i;

clock_gettime(CLOCK_MONOTONIC, &start); //현재 시간 저장
sleep(1); //1초간 sleep
clock_gettime(CLOCK_MONOTONIC, &end); //현재 시간 저장

             //시간 차 출력 (MONOTONIC)
diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec -start.tv_nsec;
printf("MONOTONIC       = %11u nanosec\n", (long long unsigned int) diff );
printf("start : %10ld sec, %06ld nanosec\n",(long int)start.tv_sec, (long int)start.tv_nsec);
printf("end   : %10ld sec, %06ld nanosec\n",(long int)end.tv_sec, (long int)end.tv_nsec);

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
sleep(1);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
           
             //시간 차 출력 (Process_CPUTime)
diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
printf("Process_CPUTime = %11u nanosec\n", (long long unsigned int) diff );
printf("start : %10ld sec, %06ld nanosec\n",(long int)start.tv_sec, (long int)start.tv_nsec);
printf("end   : %10ld sec, %06ld nanosec\n",(long int)end.tv_sec, (long int)end.tv_nsec);


clock_gettime(CLOCK_REALTIME, &start);
sleep(1);
clock_gettime(CLOCK_REALTIME, &end);

             //시간 차 출력 (RealTime)
diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
printf("RealTime        = %11u nanosec\n", (long long unsigned int) diff );
printf("start : %10ld sec, %06ld nanosec\n",(long int)start.tv_sec, (long int)start.tv_nsec);
printf("end   : %10ld sec, %06ld nanosec\n\n",(long int)end.tv_sec, (long int)end.tv_nsec);

}
}

- 결과 -


CLOCK종류에 따라 시간 기준이 다른 것을 알 수 있다.



  위의 예제는 단위가 밀리초, 아래 예제는 단위가 나노초 단위이기 때문에 단위 환산을 하여 비교해야 한다. 

 그런데 결과는 이론과는 다르게 어째 제노마이가 더 보장되지 않는 것이냐ㅠㅠ
시간을 늘려서 해보아도 같은 결과이다...


출처 :
https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/gettime.html
https://xenomai.org/documentation/trunk/html/api/trivial-periodic_8c-example.html

댓글 없음: