Fix compilation of embench

The separation did not work before, somehow.
The new approach of redefining the function names, while hacky, definitely works though.
This commit is contained in:
David Venhoff 2025-09-12 10:52:11 +02:00
parent 7666a650c2
commit 9ba2bbe8cd
22 changed files with 92 additions and 96 deletions

View File

@ -1,3 +1,5 @@
set -e
cargo build --workspace --release cargo build --workspace --release
echo "Disabling turbo..." echo "Disabling turbo..."

View File

@ -44,70 +44,57 @@ fn main() {
let embench_dir = PathBuf::from_str(&format!("{out_dir}/embench-iot")).unwrap(); let embench_dir = PathBuf::from_str(&format!("{out_dir}/embench-iot")).unwrap();
let mut generated_code = String::new(); let mut generated_code = String::new();
let mut benchmark_functions = vec![];
for &benchmark_file in BENCHMARKS { for &benchmark_file in BENCHMARKS {
let path = embench_dir.join(benchmark_file); let path = embench_dir.join(benchmark_file);
let dir = path.parent().unwrap(); let dir = path.parent().unwrap();
let benchmark_name = dir.file_name().unwrap().to_string_lossy(); let benchmark_name = dir.file_name().unwrap().to_string_lossy().replace("-", "_");
let (wrapper_path, function_name) = make_wrapper(&benchmark_name, &out_dir); println!("cargo:warning={path:?}");
cc::Build::new()
let mut build = cc::Build::new();
build
.include(embench_dir.join("support")) .include(embench_dir.join("support"))
.include(dir) .file(embench_dir.join("support/beebsc.c"))
.file(&path) .file(&path)
.file(&wrapper_path) // Just use some roughly accurate value, it just influences how long each benchmark runs
.define("CPU_MHZ", "2700") // FIXME: Use correct CPU frequency .define("CPU_MHZ", "2700");
.compile(&format!("libembench_{benchmark_name}.a"));
// Rename all functions that are defined multiple times to avoid collisions
let colliding_functions = [
"benchmark",
"initialise_benchmark",
"warm_caches",
"verify_benchmark",
];
for name in colliding_functions {
build.define(name, format!("{benchmark_name}_{name}").as_str());
}
build.compile(&format!("libembench_{benchmark_name}.a"));
write!( write!(
generated_code, generated_code,
r#" r#"
#[allow(non_camel_case_types)] pub struct {benchmark_name};
unsafe extern "C" {{ unsafe extern "C" {{
fn {function_name}(); fn {benchmark_name}_benchmark();
}}"# fn {benchmark_name}_initialise_benchmark();
) }}
.unwrap();
benchmark_functions.push(function_name);
}
writeln!( impl Benchmark for {benchmark_name} {{
generated_code, unsafe fn init() {{
"#[allow(non_camel_case_types)] #[derive(Clone, Copy)] pub enum Benchmark {{" unsafe {{ {benchmark_name}_initialise_benchmark(); }}
) }}
.unwrap();
for benchmark_name in &benchmark_functions {
writeln!(generated_code, " {benchmark_name},").unwrap();
}
writeln!(generated_code, "}}").unwrap();
writeln!(generated_code, "pub unsafe fn run(benchmark: Benchmark) {{").unwrap(); unsafe fn benchmark() {{
writeln!(generated_code, "match benchmark {{").unwrap(); unsafe {{ {benchmark_name}_benchmark(); }}
for benchmark_name in benchmark_functions { }}
writeln!( }}
generated_code, "#
" Benchmark::{benchmark_name} => unsafe {{ {benchmark_name}() }},"
) )
.unwrap(); .unwrap();
} }
writeln!(generated_code, "}}").unwrap();
writeln!(generated_code, "}}").unwrap();
fs::write(format!("{out_dir}/libembench-sys.rs"), generated_code).unwrap(); fs::write(format!("{out_dir}/libembench-sys.rs"), generated_code).unwrap();
} }
fn make_wrapper(benchmark_name: &str, out_dir: &str) -> (PathBuf, String) {
let benchmark_name = benchmark_name.replace("-", "_");
let function_name = format!("benchmark_{benchmark_name}");
let code = format!(
r#"
extern int benchmark(void);
void {function_name}(void) {{
benchmark();
}}
"#
);
let path = PathBuf::from(out_dir).join(format!("{benchmark_name}_wrapper.c"));
fs::write(&path, code).unwrap();
(path, function_name)
}

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_sglib_combined); program::<client::embench_sys::sglib_combined>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_crc32); program::<client::embench_sys::crc32>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_edn); program::<client::embench_sys::edn>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_huffbench); program::<client::embench_sys::huffbench>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_matmult_int); program::<client::embench_sys::matmult_int>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_md5sum); program::<client::embench_sys::md5sum>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_minver); program::<client::embench_sys::minver>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_aha_mont64); program::<client::embench_sys::aha_mont64>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_nbody); program::<client::embench_sys::nbody>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_nettle_aes); program::<client::embench_sys::nettle_aes>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_nettle_sha256); program::<client::embench_sys::nettle_sha256>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_nsichneu); program::<client::embench_sys::nsichneu>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_picojpeg); program::<client::embench_sys::picojpeg>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_primecount); program::<client::embench_sys::primecount>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_slre); program::<client::embench_sys::slre>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_st); program::<client::embench_sys::st>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_statemate); program::<client::embench_sys::statemate>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_tarfind); program::<client::embench_sys::tarfind>();
} }

View File

@ -1,5 +1,5 @@
use client::{Benchmark, program}; use client::program;
fn main() { fn main() {
program(Benchmark::benchmark_ud); program::<client::embench_sys::ud>();
} }

View File

@ -1,6 +1,12 @@
use std::arch::asm; use std::arch::asm;
mod embench_sys { pub mod embench_sys {
pub trait Benchmark {
unsafe fn init();
unsafe fn benchmark();
}
include!(concat!(env!("OUT_DIR"), "/libembench-sys.rs")); include!(concat!(env!("OUT_DIR"), "/libembench-sys.rs"));
} }
@ -12,14 +18,15 @@ fn ptwrite(val: u32) {
} }
} }
pub fn program(benchmark: embench_sys::Benchmark) { pub fn program<B: Benchmark>() {
let start = std::time::Instant::now(); unsafe {
for _ in std::hint::black_box(0..100) { B::init();
ptwrite(42);
unsafe {
embench_sys::run(benchmark);
}
ptwrite(43);
} }
let start = std::time::Instant::now();
ptwrite(42);
unsafe {
B::benchmark();
}
ptwrite(43);
println!("{}", start.elapsed().as_secs_f64()); println!("{}", start.elapsed().as_secs_f64());
} }