Wrote a benchmark for measuring the context switch time.
This commit is contained in:
parent
0984eb593f
commit
9b36a72f5f
2 changed files with 59 additions and 16 deletions
70
apps/tests.c
70
apps/tests.c
|
@ -301,22 +301,65 @@ static int pi(void* arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int measure_ctx_switch(void)
|
#define REPS 10000
|
||||||
{
|
|
||||||
uint64_t max = 0;
|
|
||||||
uint64_t start, t1, t2;
|
|
||||||
uint64_t freq = get_cpu_frequency();
|
|
||||||
|
|
||||||
start = t1 = rdtsc();
|
volatile uint64_t t1, t2;
|
||||||
do {
|
volatile int stop = !!0;
|
||||||
asm volatile ("cpuid");
|
volatile int sid = 0;
|
||||||
|
|
||||||
|
static int measure_ctx_switch(void* arg)
|
||||||
|
{
|
||||||
|
int id = !!(int)arg;
|
||||||
|
int oid = !id;
|
||||||
|
uint64_t freq = get_cpu_frequency() *1000 *1000;
|
||||||
|
uint64_t diff, min = (uint64_t)-1, max = 0, avg = 0;
|
||||||
|
int i;
|
||||||
|
uint32_t a=0,b,c,d;
|
||||||
|
|
||||||
|
// Size of a timeslice in ticks
|
||||||
|
uint64_t timeslice = freq / TIMER_FREQ;
|
||||||
|
|
||||||
|
kprintf("ID: %d, ", id);
|
||||||
|
#ifdef SW_TASK_SWITCH
|
||||||
|
kprintf("Measuring SW task switch.\n");
|
||||||
|
#else
|
||||||
|
kprintf("Measuring HW task switch.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i=0; i < REPS && stop == 0; i++) {
|
||||||
|
while(id == sid && stop == 0) {
|
||||||
t2 = rdtsc();
|
t2 = rdtsc();
|
||||||
if (t2 - t1 > max)
|
cpuid(0,&a,&b,&c,&d);
|
||||||
max = t2 - t1;
|
}
|
||||||
t1 = t2;
|
|
||||||
} while(t2-start < 10*freq);
|
cpuid(0,&a,&b,&c,&d);
|
||||||
|
diff = rdtsc() -t2;
|
||||||
|
|
||||||
|
// The last measurement is garbage
|
||||||
|
if (stop) break;
|
||||||
|
// The first ones are garbage, too
|
||||||
|
if (i < 5) goto next_try;
|
||||||
|
if (diff >= timeslice) {
|
||||||
|
i--;
|
||||||
|
goto next_try;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("%i: diff= %llu, i= %i\n", id, diff, i);
|
||||||
|
if (diff > max) max = diff;
|
||||||
|
if (diff < min) min = diff;
|
||||||
|
avg += diff;
|
||||||
|
|
||||||
|
next_try:
|
||||||
|
sid = id;
|
||||||
|
}
|
||||||
|
avg /= i-5;
|
||||||
|
|
||||||
|
stop = 1;
|
||||||
|
|
||||||
kprintf("maximum gap: %llu ticks\n", max);
|
kprintf("maximum gap: %llu ticks\n", max);
|
||||||
|
kprintf("minimum gap: %llu ticks\n", min);
|
||||||
|
kprintf("average gap: %llu ticks\n", avg);
|
||||||
|
kprintf("Timeslice size: %llu ticks\n", timeslice);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +375,8 @@ int test_init(void)
|
||||||
sem_init(&consuming, 0);
|
sem_init(&consuming, 0);
|
||||||
mailbox_int32_init(&mbox);
|
mailbox_int32_init(&mbox);
|
||||||
|
|
||||||
create_kernel_task(NULL, measure_ctx_switch, NULL, NORMAL_PRIO);
|
create_kernel_task(NULL, measure_ctx_switch, (int)0, NORMAL_PRIO);
|
||||||
|
create_kernel_task(NULL, measure_ctx_switch, (int)1, NORMAL_PRIO);
|
||||||
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
|
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
|
||||||
//create_kernel_task(NULL, foo, "Hello from foo2", NORMAL_PRIO);
|
//create_kernel_task(NULL, foo, "Hello from foo2", NORMAL_PRIO);
|
||||||
//create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
|
//create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
|
||||||
|
|
|
@ -1378,8 +1378,7 @@ get_task_out:
|
||||||
orig_task->flags &= ~TASK_FPU_USED;
|
orig_task->flags &= ~TASK_FPU_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
//kprintf("schedule from %u to %u with prio %u on core %u\n",
|
//kprintf("schedule from %u to %u with prio %u on core %u\n", orig_task->id, curr_task->id, (uint32_t)curr_task->prio, CORE_ID);
|
||||||
// orig_task->id, curr_task->id, (uint32_t)curr_task->prio, CORE_ID);
|
|
||||||
#ifndef SW_TASK_SWITCH
|
#ifndef SW_TASK_SWITCH
|
||||||
switch_task(curr_task->id);
|
switch_task(curr_task->id);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue