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;
|
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)
|
int hermit_main(void)
|
||||||
{
|
{
|
||||||
hermit_init();
|
hermit_init();
|
||||||
|
@ -608,7 +683,12 @@ int hermit_main(void)
|
||||||
print_cpu_status(isle);
|
print_cpu_status(isle);
|
||||||
//vma_dump();
|
//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);
|
create_kernel_task_on_core(NULL, initd, NULL, NORMAL_PRIO, boot_processor);
|
||||||
|
#endif
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
check_workqueues();
|
check_workqueues();
|
||||||
|
|
|
@ -17,7 +17,5 @@ add_executable(stream stream.c)
|
||||||
target_compile_options(stream PRIVATE -fopenmp)
|
target_compile_options(stream PRIVATE -fopenmp)
|
||||||
target_link_libraries(stream -fopenmp)
|
target_link_libraries(stream -fopenmp)
|
||||||
|
|
||||||
add_executable(taskswitch taskswitch.c)
|
|
||||||
|
|
||||||
# deployment
|
# deployment
|
||||||
install_local_targets(extra/benchmarks)
|
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