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:
parent
7cf050cf30
commit
0bd1df6052
3 changed files with 80 additions and 152 deletions
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue