Phase 10_6b scheduler complete; 10_4 GC hooks + counting/strict tracing; 10_c minimal JIT path (i64/bool consts, binop/compare/return, hostcall opt-in); docs & examples; add Phase 10.7 roadmap (JIT branch wiring + minimal ABI).
This commit is contained in:
@ -5,33 +5,73 @@ impl NyashRunner {
|
||||
/// Execute benchmark mode (split)
|
||||
pub(crate) fn execute_benchmark_mode(&self) {
|
||||
println!("🏁 Running benchmark mode with {} iterations", self.config.iterations);
|
||||
let test_code = r#"
|
||||
local x
|
||||
x = 42
|
||||
local y
|
||||
y = x + 58
|
||||
return y
|
||||
"#;
|
||||
// Two tests: simple add, arithmetic loop
|
||||
let tests: Vec<(&str, &str)> = vec![
|
||||
(
|
||||
"simple_add",
|
||||
r#"
|
||||
local x
|
||||
x = 42
|
||||
local y
|
||||
y = x + 58
|
||||
return y
|
||||
"#,
|
||||
),
|
||||
(
|
||||
"arith_loop_100k",
|
||||
r#"
|
||||
local i, sum
|
||||
i = 0
|
||||
sum = 0
|
||||
loop(i < 100000) {
|
||||
sum = sum + i
|
||||
i = i + 1
|
||||
}
|
||||
return sum
|
||||
"#,
|
||||
),
|
||||
];
|
||||
|
||||
println!("\n🧪 Test code:\n{}", test_code);
|
||||
for (name, code) in tests {
|
||||
println!("\n====================================");
|
||||
println!("🧪 Test: {}", name);
|
||||
// Warmup (not measured)
|
||||
let warmup = (self.config.iterations / 10).max(1);
|
||||
self.bench_interpreter(code, warmup);
|
||||
self.bench_vm(code, warmup);
|
||||
self.bench_jit(code, warmup);
|
||||
|
||||
// Interpreter
|
||||
println!("\n⚡ Interpreter Backend:");
|
||||
// Measured runs
|
||||
let interpreter_time = self.bench_interpreter(code, self.config.iterations);
|
||||
let vm_time = self.bench_vm(code, self.config.iterations);
|
||||
let jit_time = self.bench_jit(code, self.config.iterations);
|
||||
|
||||
// Summary
|
||||
let vm_vs_interp = interpreter_time.as_secs_f64() / vm_time.as_secs_f64();
|
||||
let jit_vs_vm = vm_time.as_secs_f64() / jit_time.as_secs_f64();
|
||||
println!("\n📊 Performance Summary [{}]:", name);
|
||||
println!(" VM is {:.2}x {} than Interpreter", if vm_vs_interp > 1.0 { vm_vs_interp } else { 1.0 / vm_vs_interp }, if vm_vs_interp > 1.0 { "faster" } else { "slower" });
|
||||
println!(" JIT is {:.2}x {} than VM (note: compile cost included)", if jit_vs_vm > 1.0 { jit_vs_vm } else { 1.0 / jit_vs_vm }, if jit_vs_vm > 1.0 { "faster" } else { "slower" });
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_interpreter(&self, code: &str, iters: u32) -> std::time::Duration {
|
||||
let start = std::time::Instant::now();
|
||||
for _ in 0..self.config.iterations {
|
||||
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
|
||||
for _ in 0..iters {
|
||||
if let Ok(ast) = NyashParser::parse_from_string(code) {
|
||||
let mut interp = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
|
||||
let _ = interp.execute(ast);
|
||||
}
|
||||
}
|
||||
let interpreter_time = start.elapsed();
|
||||
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, interpreter_time, self.config.iterations as f64 / interpreter_time.as_secs_f64());
|
||||
let elapsed = start.elapsed();
|
||||
println!(" ⚡ Interpreter: {} iters in {:?} ({:.2} ops/sec)", iters, elapsed, iters as f64 / elapsed.as_secs_f64());
|
||||
elapsed
|
||||
}
|
||||
|
||||
// VM
|
||||
println!("\n🚀 VM Backend:");
|
||||
fn bench_vm(&self, code: &str, iters: u32) -> std::time::Duration {
|
||||
let start = std::time::Instant::now();
|
||||
for _ in 0..self.config.iterations {
|
||||
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
|
||||
for _ in 0..iters {
|
||||
if let Ok(ast) = NyashParser::parse_from_string(code) {
|
||||
let mut mc = MirCompiler::new();
|
||||
if let Ok(cr) = mc.compile(ast) {
|
||||
let mut vm = VM::new();
|
||||
@ -39,12 +79,27 @@ impl NyashRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
let vm_time = start.elapsed();
|
||||
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, vm_time, self.config.iterations as f64 / vm_time.as_secs_f64());
|
||||
let elapsed = start.elapsed();
|
||||
println!(" 🚀 VM: {} iters in {:?} ({:.2} ops/sec)", iters, elapsed, iters as f64 / elapsed.as_secs_f64());
|
||||
elapsed
|
||||
}
|
||||
|
||||
// Summary
|
||||
let speedup = interpreter_time.as_secs_f64() / vm_time.as_secs_f64();
|
||||
println!("\n📊 Performance Summary:\n VM is {:.2}x {} than Interpreter", if speedup > 1.0 { speedup } else { 1.0 / speedup }, if speedup > 1.0 { "faster" } else { "slower" });
|
||||
fn bench_jit(&self, code: &str, iters: u32) -> std::time::Duration {
|
||||
// Force JIT mode for this run
|
||||
std::env::set_var("NYASH_JIT_EXEC", "1");
|
||||
std::env::set_var("NYASH_JIT_THRESHOLD", "1");
|
||||
let start = std::time::Instant::now();
|
||||
for _ in 0..iters {
|
||||
if let Ok(ast) = NyashParser::parse_from_string(code) {
|
||||
let mut mc = MirCompiler::new();
|
||||
if let Ok(cr) = mc.compile(ast) {
|
||||
let mut vm = VM::new();
|
||||
let _ = vm.execute_module(&cr.module);
|
||||
}
|
||||
}
|
||||
}
|
||||
let elapsed = start.elapsed();
|
||||
println!(" 🔥 JIT: {} iters in {:?} ({:.2} ops/sec)", iters, elapsed, iters as f64 / elapsed.as_secs_f64());
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,9 +20,12 @@ impl NyashRunner {
|
||||
|
||||
// Prepare runtime and collect Box declarations for VM user-defined types
|
||||
let runtime = {
|
||||
let rt = NyashRuntimeBuilder::new()
|
||||
.with_builtin_groups(BuiltinGroups::native_full())
|
||||
.build();
|
||||
let mut builder = NyashRuntimeBuilder::new()
|
||||
.with_builtin_groups(BuiltinGroups::native_full());
|
||||
if std::env::var("NYASH_GC_COUNTING").ok().as_deref() == Some("1") {
|
||||
builder = builder.with_counting_gc();
|
||||
}
|
||||
let rt = builder.build();
|
||||
self.collect_box_declarations(&ast, &rt);
|
||||
// Register UserDefinedBoxFactory backed by the same declarations
|
||||
let mut shared = SharedState::new();
|
||||
@ -39,6 +42,20 @@ impl NyashRunner {
|
||||
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||
};
|
||||
|
||||
// Optional: demo scheduling hook
|
||||
if std::env::var("NYASH_SCHED_DEMO").ok().as_deref() == Some("1") {
|
||||
if let Some(s) = &runtime.scheduler {
|
||||
// Immediate task
|
||||
s.spawn("demo-immediate", Box::new(|| {
|
||||
println!("[SCHED] immediate task ran at safepoint");
|
||||
}));
|
||||
// Delayed task
|
||||
s.spawn_after(0, "demo-delayed", Box::new(|| {
|
||||
println!("[SCHED] delayed task ran at safepoint");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Execute with VM using prepared runtime
|
||||
let mut vm = VM::with_runtime(runtime);
|
||||
match vm.execute_module(&compile_result.module) {
|
||||
@ -81,4 +98,3 @@ impl NyashRunner {
|
||||
walk(ast, runtime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user