1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-30 00:00:15 +01:00

move benchmark to libhermit to avoid side effects with LwIP

This commit is contained in:
Stefan Lankes 2018-04-30 08:02:45 +02:00
parent 7cf050cf30
commit 0bd1df6052
3 changed files with 80 additions and 152 deletions

View file

@ -569,6 +569,81 @@ out:
return 0;
}
//#define MEASURE_CONTEXT
#ifdef MEASURE_CONTEXT
#define N 10000
volatile int finished = 0;
volatile int started1 = 0;
volatile int started2 = 0;
static int dummy_task(void* arg)
{
kprintf("Enter dummy loop at core %d\n", CORE_ID);
// cache warm up
reschedule();
reschedule();
// synchronize start
started2 = 1;
mb();
while(started1 == 0)
reschedule();
while (finished == 0)
{
reschedule();
}
kprintf("Leave dummy loop\n");
return 0;
}
static int measure_context(void* arg)
{
unsigned long long start, end;
kprintf("Enter function at core %d to measure the time for a context switch\n", CORE_ID);
// cache warm up
reschedule();
reschedule();
// synchronize start
started1 = 1;
mb();
while(started2 == 0)
reschedule();
// Save the current Time Stamp Counter value and switch to the second task.
start = rdtsc();
mb();
for(uint32_t i = 0; i < N; i++)
{
reschedule();
}
// Calculate the cycle difference and add it to the sum.
end = rdtsc();
mb();
finished = 1;
reschedule();
reschedule();
kprintf("Average time for a task switch: %lld cycles\n", (end - start) / (N * 2));
sys_exit(0);
return 0;
}
#endif
int hermit_main(void)
{
hermit_init();
@ -608,7 +683,12 @@ int hermit_main(void)
print_cpu_status(isle);
//vma_dump();
#ifdef MEASURE_CONTEXT
create_kernel_task_on_core(NULL, dummy_task, NULL, NORMAL_PRIO, boot_processor);
create_kernel_task_on_core(NULL, measure_context, NULL, NORMAL_PRIO, boot_processor);
#else
create_kernel_task_on_core(NULL, initd, NULL, NORMAL_PRIO, boot_processor);
#endif
while(1) {
check_workqueues();

View file

@ -17,7 +17,5 @@ add_executable(stream stream.c)
target_compile_options(stream PRIVATE -fopenmp)
target_link_libraries(stream -fopenmp)
add_executable(taskswitch taskswitch.c)
# deployment
install_local_targets(extra/benchmarks)

View file

@ -1,150 +0,0 @@
// Copyright (c) 2018 Colin Finck, RWTH Aachen University
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////
//// HERMITCORE C-SPECIFIC CODE ////
#include <hermit/syscall.h>
#define NORMAL_PRIO 8
typedef int (*entry_point_t)(void*);
int create_kernel_task_on_core(tid_t* id, entry_point_t ep, void* args, uint8_t prio, uint32_t core_id);
void reschedule(void);
inline static void create_second_task(void (*entry_point)(void*))
{
create_kernel_task_on_core(NULL, (entry_point_t)entry_point, NULL, NORMAL_PRIO, 0);
}
inline static void consume_task_time(void)
{
// Not required for the HermitCore C version.
}
inline static void switch_task(void)
{
reschedule();
}
///////////////////////////////////
//// THE ACTUAL BENCHMARK CODE ////
#include <stdbool.h>
#include <stdio.h>
// You can enable this for debugging without any effect on the measurement.
//#define DEBUG_MESSAGES
#define N 1000
static bool finished;
static unsigned long long start;
static unsigned long long sum;
inline static unsigned long long rdtsc(void)
{
unsigned long lo, hi;
asm volatile ("rdtsc" : "=a"(lo), "=d"(hi) :: "memory");
return ((unsigned long long) hi << 32ULL | (unsigned long long) lo);
}
void second_task(void* arg)
{
unsigned long long end;
for(;;)
{
// Calculate the cycle difference and add it to the sum.
end = rdtsc();
sum += (end - start);
// Check if the benchmark has finished and we can end the second task.
if (finished)
{
break;
}
#ifdef DEBUG_MESSAGES
printf("Hello from task 2\n");
#endif
consume_task_time();
// Save the current Time Stamp Counter value and switch back to the
// first task.
start = rdtsc();
switch_task();
}
}
int main(int argc, char** argv)
{
int i;
unsigned long long end;
// Start the second task with the same priority on the boot processor.
create_second_task(second_task);
// Initialize the benchmark.
printf("taskswitch test\n");
printf("===============\n");
finished = false;
sum = 0;
// Warm up
switch_task();
switch_task();
// Run the benchmark.
sum = 0;
for(i = 0; i < N; i++)
{
#ifdef DEBUG_MESSAGES
printf("Hello from task 1\n");
#endif
consume_task_time();
// Save the current Time Stamp Counter value and switch to the second
// task.
start = rdtsc();
switch_task();
// Calculate the cycle difference and add it to the sum.
end = rdtsc();
sum += (end - start);
}
// Calculate and print the results.
// In every loop iteration, task 1 switches to task 2 and task 2 switches
// back to task 1.
// Therefore, the total number needs to be divided by 2.
printf("Average time for a task switch: %lld cycles\n", sum / (N * 2));
// Finish the second task gracefully.
finished = true;
switch_task();
return 0;
}