Hi guys,

I have installed a Debian+Xenomai (2.6.0) OS on my Gumstix Overo.

I want to evaluate the execution time of a simple program, executed as a
real-time thread.

I definitely wonder about which functions to use, as I have completely
inconsistent measures.
I have tried using rt_timer_read, rt_timer_tsc, clock_gettime.
I also directly read the CNNT register with ARM instructions (which is the
only one I think correct) in order to have a (good?) reference.

I join the simple program I use.

The output is :
----- ASM instruction -----
start: 62483 ; end: 172961 ; (s-e): 110478 ; overhead: 102 ;
(s-e-overhead): 110376 ; CET: 110478
----- Xenomai rt_timer_read -----
start: 1016 ; end: 3435090911 ; (s-e): 1016 ; CET: 3435246834
----- Xenomai rt_timer_tsc -----
start: 13 ; end: 938009132 ; (s-e): 13 ; CET: 938011124
----- Xenomai clock_gettime -----
[ s] start: 946689173 ; end: 946689173 ; (s-e): 0 ; CET: 0
[ns] start: 231412764 ; end: 231569761 ; (s-e): 156997 ; CET: 156997

So that I can support that the correct execution time is around 110 000
(ticks?)

Only the nsecs of clock_gettime seem to be consistent ; other functions
return erratic values!

What am I doing wrong?

Should I initialize something in my program (I tried
rt_timer_set_mode(TM_ONESHOT) without any change)?

Should I check or change my kernel or xenomai configuration options?

Any (urgent) help would be appreciated!

Thanks,

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

#include <native/task.h>
#include <native/timer.h>
#include <rtdk.h>
#include <posix/time.h>

RT_TASK task;

int sum() {
	int i = 0;
	int s = 0;
	for(i = 0; i < 10000; i++)
    	s += i;
	return s;
}

static inline unsigned long int get_cyclecount (void)
{
  unsigned long int value;
  //MRC p15, 0, <Rd>, c9, c13, 0 ; Read CCNT Register
  asm volatile ("MRC p15, 0, %[Rd], c9, c13, 0\t\n": [Rd] "=r"(value));
  return value;
}

static inline void init_perfcounters (int32_t do_reset, int32_t enable_divider)
{
  // in general enable all counters (including cycle counter)
  int32_t value = 1;
  // peform reset:
  if (do_reset)
  {
    value |= 2;     // reset all counters to zero.
    value |= 4;     // reset cycle counter to zero.
  }
  if (enable_divider)
    value |= 8;     // enable "by 64" divider for CCNT.
  value |= 16;
  // program the performance-counter control-register:
  asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));
    // enable all counters:
  asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));
  // clear overflows:
  asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
}

void sum_task(void *arg) {
	// Init ASM registers
	init_perfcounters(1, 0);
	// Init Timer
    rt_timer_set_mode(TM_ONESHOT);

	rt_printf("----- ASM instruction -----\n");
	unsigned long int asm_s, asm_e, asm_c, asm_o;
	asm_o = get_cyclecount(); asm_o = get_cyclecount() - asm_o;
	asm_s = get_cyclecount();
	sum();
	asm_e = get_cyclecount();
	asm_c = asm_e - asm_s;
	rt_printf("start: %lu ; end: %lu ; (s-e): %lu ; overhead: %lu ; (s-e-overhead): %lu ; CET: %lu \n",
		asm_s, asm_e, (asm_e - asm_s), asm_o, ((asm_e-asm_s)-asm_o), asm_c);

	rt_printf("----- Xenomai rt_timer_read -----\n");
	RTIME read_s, read_e, read_c;
	read_s = rt_timer_read();
	sum();
	read_e = rt_timer_read();
	read_c = read_e - read_s;
	rt_printf("start: %lu ; end: %lu ; (s-e): %lu ; CET: %lu \n", read_s, read_e, (read_e - read_s), read_c);

	rt_printf("----- Xenomai rt_timer_tsc -----\n");
	RTIME tsc_s, tsc_e, tsc_c;
	tsc_s = rt_timer_tsc();
	sum();
	tsc_e = rt_timer_tsc();
	tsc_c = tsc_e - tsc_s;
	rt_printf("start: %lu ; end: %lu ; (s-e): %lu ; CET: %lu \n", tsc_s, tsc_e, (tsc_e - tsc_s), tsc_c);

	rt_printf("----- Xenomai clock_gettime -----\n");
	struct timespec clock_s, clock_e, clock_c;
	clock_gettime(CLOCK_REALTIME, &clock_s);
	sum();
	clock_gettime(CLOCK_REALTIME, &clock_e);
	clock_c.tv_sec = clock_e.tv_sec - clock_s.tv_sec;
	clock_c.tv_nsec = clock_e.tv_nsec - clock_s.tv_nsec;
	rt_printf("[ s] start: %d ; end: %d ; (s-e): %d ; CET: %d \n",
			clock_s.tv_sec, clock_e.tv_sec, (clock_e.tv_sec - clock_s.tv_sec), clock_c.tv_sec);
	rt_printf("[ns] start: %d ; end: %d ; (s-e): %d ; CET: %d \n",
			clock_s.tv_nsec, clock_e.tv_nsec, (clock_e.tv_nsec - clock_s.tv_nsec), clock_c.tv_nsec);
}


int main(int argc, char* argv[]) {
	char str[10] ;
	// Perform auto-init of rt_print buffers if the task doesn't do so
	rt_print_auto_init(1);
	// Lock memory : avoid memory swapping for this program
	mlockall(MCL_CURRENT | MCL_FUTURE);
	sprintf(str, "sum_test");
	// rt_task_create(task, task name, stack size, priority, mode
	rt_task_create(&task, str, 0, 50, 0);
	// rt_task_start(task, task function, function argument
	rt_task_start(&task, &sum_task, 0);
	rt_task_join(&task);
}
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to