os: automate cpu_bench testsuite

* Differentiate in between different architectures with assembler routines
  for correct measures
* Automate first step measuring of 10G bogomips across different hardware

Fix #3785
This commit is contained in:
Stefan Kalkowski 2020-06-19 16:41:20 +02:00 committed by Norman Feske
parent ef741ef80d
commit 1cfb1af56e
21 changed files with 233 additions and 66 deletions

View File

@ -5,52 +5,67 @@ if { [get_cmd_switch --autopilot] } {
}
}
if {[have_spec linux] || [have_spec riscv]} {
puts "\n Run script is not supported on this platform. \n";
exit 0
}
build "core init timer test/cpu_bench"
create_boot_directory
install_config {
<config prio_levels="2">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
</parent-provides>
<default-route> <any-service> <parent/> <any-child/> </any-service> </default-route>
<default caps="200"/>
<start name="timer" caps="64" priority="0">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="test-cpu" priority="-1">
<resource name="RAM" quantum="1M"/>
</start>
</config>
<config>
<parent-provides>
<service name="LOG"/>
<service name="CPU"/>
<service name="ROM"/>
<service name="PD"/>
</parent-provides>
<default-route>
<any-service> <parent/> </any-service>
</default-route>
<default caps="100"/>
<start name="cpu_bench">
<resource name="RAM" quantum="10M"/>
</start>
</config>
}
build_boot_image {
core init test-cpu ld.lib.so timer
}
build_boot_image { core init cpu_bench ld.lib.so }
append qemu_args " -nographic "
proc run_test {name serial_id} {
run_genode_until "start $name.*\n" 20 $serial_id
set t1 [clock milliseconds]
run_genode_until "finished $name.*\n" 200 $serial_id
set t2 [clock milliseconds]
return [expr {$t2 - $t1}]
#
# Those value relate to hardware used in CI testsuite used at Genode Labs,
# as well as the initialization of their bootloaders, we use this to measure
# regressions in the platform initialization code
#
proc bogomips_max_time { } {
if {[board] == "rpi"} { return 14300 }
if {[board] == "imx53_qsb"} { return 7520 }
if {[board] == "imx53_qsb_tz"} { return 7520 }
if {[board] == "imx6q_sabrelite"} { return 6320 }
if {[board] == "imx7d_sabre"} { return 9470 }
if {[board] == "imx8q_evk"} { return 7510 }
if {[have_spec x86_64] && [[board] == "pc"]} { return 600 }
if {[have_spec x86_32] && [[board] == "pc"]} { return 3150 }
return 0
}
run_genode_until "Cpu testsuite started" 60
# run the test
run_genode_until {\[init -\> cpu_bench\] Execute 10G BogoMIPS.*\n} 120
set serial_id [output_spawn_id]
set bogomips [run_test "bogomips" $serial_id]
puts "bogomips: 2G Bogus instructions in $bogomips milliseconds ([expr {2000000.0 / $bogomips}] BogoMIPS)"
set t1 [clock milliseconds]
run_genode_until "Finished execution.*\n" 30 $serial_id
set t2 [clock milliseconds]
set result [expr {$t2 - $t1}]
set bogomips [expr {10000000000 / $result}]
set maximum [bogomips_max_time]
puts "10G bogus instructions in $result msecs ($bogomips BogoMIPS)"
if {$result > $maximum} {
puts "Test failed: bogomips loop lasted longer than $maximum msecs"
exit 1
}
exit 0

View File

@ -1,8 +1,18 @@
/*
* \brief Testing CPU performance
* \author Stefan Kalkowski
* \date 2018-10-22
*
*/
void bogomips() __attribute__((optimize("O0")));
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
void bogomips()
{
for (register unsigned i = 0; i < 1000000000; i++) ;
};
#pragma once
extern "C" void bogomips(unsigned long);
extern "C" unsigned long bogomips_instr_count(void);

View File

@ -1,7 +0,0 @@
INC_DIR = $(PWD)/..
cpu_bench: main.cc $(INC_DIR)/bogomips.h
g++ -I$(INC_DIR) -O2 -Wall -Wextra -Weffc++ -std=gnu++11 $< -o $@
clean:
rm -f *~ cpu_bench

View File

@ -0,0 +1,14 @@
OBJECTS := main.o bogomips.o
GEN_DIR = $(LINUX_DIR)/..
cpu_bench: $(OBJECTS)
g++ $(OBJECTS) -o $@
main.o: $(LINUX_DIR)/main.cc $(GEN_DIR)/bogomips.h
g++ -c -I$(GEN_DIR) -O2 -Wall -Wextra -Weffc++ -std=gnu++11 $< -o $@
bogomips.o: ../bogomips.s
gcc -c -O2 -Wall -Wextra $< -o $@
clean:
rm -f *~ cpu_bench bogomips.o main.o

View File

@ -20,14 +20,14 @@ struct Time
void print() const
{
printf("secs=%ld nsecs=%ld\n",
(long)_timespec.tv_sec, (long)_timespec.tv_nsec);
(long)_timespec.tv_sec, (long)_timespec.tv_nsec);
}
static Duration duration(Time t1, Time t2)
{
auto usecs = [&] (timespec ts) {
return 1000UL*1000UL*((unsigned long)ts.tv_sec % 1000UL)
+ (unsigned long)ts.tv_nsec/1000UL; };
+ (unsigned long)ts.tv_nsec/1000UL; };
return Duration { usecs(t2._timespec) - usecs(t1._timespec) };
}
@ -36,13 +36,18 @@ struct Time
int main(int, char**)
{
printf("bogomips test:\n");
unsigned long instr_per_round = bogomips_instr_count();
unsigned long rounds = 1000UL*1000UL*1000UL / instr_per_round * 10UL;
printf("Execute 10G BogoMIPS in %lu rounds with %lu instr per round\n",
rounds, instr_per_round);
Time s;
bogomips();
bogomips(rounds);
{
Time e;
Duration duration = Time::duration(s, e);
printf("2G bogus instructions in %ld msecs (%f BogoMIPS)\n",
duration.usecs/1000, 2000000000 / (float)duration.usecs);
printf("10G bogus instructions in %lu msecs\n", duration.usecs/1000);
}
}

View File

@ -14,17 +14,19 @@
#include <base/component.h>
#include <base/log.h>
#include <timer_session/connection.h>
#include <bogomips.h>
void Component::construct(Genode::Env &env)
void Component::construct(Genode::Env &)
{
Timer::Connection timer(env);
timer.msleep(2000);
using namespace Genode;
Genode::log("Cpu testsuite started");
Genode::log("start bogomips");
bogomips();
Genode::log("finished bogomips");
log("Cpu testsuite started");
size_t cnt = 1000*1000*1000 / bogomips_instr_count() * 10;
log("Execute 10G BogoMIPS in ", cnt, " rounds with ",
bogomips_instr_count(), " instructions each");
bogomips(cnt);
log("Finished execution");
};

View File

@ -0,0 +1,28 @@
.section .text
.balign 4096
.global bogomips
bogomips:
push { r4, lr }
mov r4, #0
1:
cmp r4, r0
addne r4, r4, #1
.rept 1
nop
.endr
bne 1b
2:
pop { r4, lr }
mov pc, lr
.global bogomips_instr_count
bogomips_instr_count:
push { r4, r5, lr }
adr r4, 1b
adr r5, 2b
sub r0, r5, r4
lsr r0, r0, #2
pop { r4, r5, lr }
mov pc, lr

View File

@ -0,0 +1,3 @@
LINUX_DIR = $(PWD)/../../../linux
include $(LINUX_DIR)/Makefile.inc

View File

@ -0,0 +1,3 @@
REQUIRES = arm
include $(PRG_DIR)/../../target.inc

View File

@ -0,0 +1,24 @@
.section .text
.balign 4096
.global bogomips
bogomips:
mov x9, x0
1:
cbz x9, 2f
sub x9, x9, #1
.rept 1
nop
.endr
b 1b
2:
ret
.global bogomips_instr_count
bogomips_instr_count:
adr x9, 1b
adr x10, 2b
sub x0, x10, x9
lsr x0, x0, #2
ret

View File

@ -0,0 +1,3 @@
LINUX_DIR = $(PWD)/../../../linux
include $(LINUX_DIR)/Makefile.inc

View File

@ -0,0 +1,3 @@
REQUIRES = arm_64
include $(PRG_DIR)/../../target.inc

View File

@ -0,0 +1,26 @@
.section .text
.balign 4096
.global bogomips
bogomips:
push %ebp
mov %esp, %ebp
mov 0x8(%ebp), %eax
1:
cmp $0x0, %eax
je 2f
sub $0x1, %eax
.rept 1
nop
.endr
jmp 1b
2:
mov %ebp, %esp
pop %ebp
ret
.global bogomips_instr_count
bogomips_instr_count:
mov $0x5, %eax
ret

View File

@ -0,0 +1,3 @@
LINUX_DIR = $(PWD)/../../../linux
include $(LINUX_DIR)/Makefile.inc

View File

@ -0,0 +1,3 @@
REQUIRES = x86_32
include $(PRG_DIR)/../../target.inc

View File

@ -0,0 +1,23 @@
.section .text
.balign 4096
.global bogomips
bogomips:
push %rdi
1:
cmp $0x0, %rdi
je 2f
sub $0x1, %rdi
.rept 1
nop
.endr
jmp 1b
2:
pop %rdi
ret
.global bogomips_instr_count
bogomips_instr_count:
mov $0x5, %rax
ret

View File

@ -0,0 +1,3 @@
LINUX_DIR = $(PWD)/../../../linux
include $(LINUX_DIR)/Makefile.inc

View File

@ -0,0 +1,3 @@
REQUIRES = x86_64
include $(PRG_DIR)/../../target.inc

View File

@ -0,0 +1,7 @@
TARGET = cpu_bench
INC_DIR = $(PRG_DIR)/../..
SRC_CC = main.cc
SRC_S = bogomips.s
LIBS = base
vpath main.cc $(PRG_DIR)/../..

View File

@ -1,5 +0,0 @@
TARGET = test-cpu
SRC_CC = main.cc
INC_DIR = $(PRG_DIR)
LIBS = base
CC_WARN = -Wno-register

View File

@ -1,4 +1,5 @@
bomb
cpu_bench
cpu_quota
cpu_sampler
demo