From c363102302cf79fd91a7ac30570d0f1250560e8a Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 28 Sep 2026 18:42:42 +0000 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=B1=A0=E6=9E=84=E9=80=A0=E6=97=B6?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=A2=84=E7=83=AD=20min=5Fsize=20=E4=B8=AA?= =?UTF-8?q?=20Vm=20=E5=B9=B6=E5=88=A0=E9=99=A4=E4=B8=89=E4=B8=AA=E6=AD=BB?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=97=97=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/kernel/config.rs | 22 +++-------- crates/oxide_kernel/tests/kernel_tests.rs | 2 - crates/oxide_vm/src/vm_pool.rs | 47 ++++++++++++++++++++--- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/crates/oxide_kernel/src/kernel/config.rs b/crates/oxide_kernel/src/kernel/config.rs index d4337ebe..5a9572bb 100644 --- a/crates/oxide_kernel/src/kernel/config.rs +++ b/crates/oxide_kernel/src/kernel/config.rs @@ -1,10 +1,10 @@ //! kernel 运行配置:VM 池规模、步数/调用深度/单 run 分配上限、session GC 阈值、 -//! perm interner 重建阈值、日志级别与内置对象预热开关(三预设 minimal/standard/full)。 +//! perm interner 重建阈值、日志级别(三预设 minimal/standard/full)。 use oxide_log::{Level, SUBSYSTEM_COUNT}; /// kernel 运行配置:VM 池规模、步数/调用深度/单 run 分配上限、session GC 阈值、 -/// perm interner 重建阈值、日志级别与内置对象预热开关。由三个预设构造器 +/// perm interner 重建阈值、日志级别。由三个预设构造器 /// ([`KernelConfig::minimal`] / [`KernelConfig::standard`] / [`KernelConfig::full`]) /// 或默认值创建。 #[derive(Clone)] @@ -26,13 +26,10 @@ pub struct KernelConfig { pub session_gc_threshold: usize, pub max_cached_modules: usize, pub log_levels: [Level; SUBSYSTEM_COUNT], - pub warmup_builtin_shapes: bool, - pub warmup_builtin_code: bool, - pub warmup_builtin_ic: bool, } impl KernelConfig { - /// 最小配置:小 VM 池、关闭 code/IC 预热,适合嵌入式或单次执行场景。 + /// 最小配置:小 VM 池,适合嵌入式或单次执行场景。 pub fn minimal() -> Self { Self { min_pool_size: 4, @@ -44,13 +41,10 @@ impl KernelConfig { session_gc_threshold: 33_554_432, max_cached_modules: 512, log_levels: [Level::Off; SUBSYSTEM_COUNT], - warmup_builtin_shapes: true, - warmup_builtin_code: false, - warmup_builtin_ic: false, } } - /// 标准配置:默认 VM 池大小,开启内置对象 code 预热。 + /// 标准配置:默认 VM 池大小。 pub fn standard() -> Self { Self { min_pool_size: 8, @@ -62,13 +56,10 @@ impl KernelConfig { session_gc_threshold: 33_554_432, max_cached_modules: 512, log_levels: [Level::Off; SUBSYSTEM_COUNT], - warmup_builtin_shapes: true, - warmup_builtin_code: true, - warmup_builtin_ic: false, } } - /// 全量配置:无上限 VM 池,开启 shapes/code/IC 全量预热,为性能场景服务。 + /// 全量配置:无上限 VM 池,为性能场景服务。 pub fn full() -> Self { Self { min_pool_size: 16, @@ -80,9 +71,6 @@ impl KernelConfig { session_gc_threshold: 33_554_432, max_cached_modules: 512, log_levels: [Level::Off; SUBSYSTEM_COUNT], - warmup_builtin_shapes: true, - warmup_builtin_code: true, - warmup_builtin_ic: true, } } diff --git a/crates/oxide_kernel/tests/kernel_tests.rs b/crates/oxide_kernel/tests/kernel_tests.rs index 7e89bb3f..f4ad9a71 100644 --- a/crates/oxide_kernel/tests/kernel_tests.rs +++ b/crates/oxide_kernel/tests/kernel_tests.rs @@ -45,8 +45,6 @@ fn test_kernel_config_presets() { assert_eq!(KernelConfig::standard().max_steps, None); assert_eq!(KernelConfig::full().max_steps, None); assert_eq!(KernelConfig::minimal().log_levels, [Level::Off; SUBSYSTEM_COUNT]); - assert!(!KernelConfig::minimal().warmup_builtin_ic); - assert!(KernelConfig::full().warmup_builtin_ic); assert_eq!(KernelConfig::full().max_pool_size, None); } diff --git a/crates/oxide_vm/src/vm_pool.rs b/crates/oxide_vm/src/vm_pool.rs index 279fdddf..027ad9d8 100644 --- a/crates/oxide_vm/src/vm_pool.rs +++ b/crates/oxide_vm/src/vm_pool.rs @@ -34,17 +34,26 @@ pub struct VmGuard { } impl VmPool { - /// 创建空池。`min_size` 当前仅作预热预留(未使用),`max_size` 为池上限,`None` 表示不限。 - pub fn new(kernel_core: Arc, _min_size: usize, max_size: Option) -> Arc { - Arc::new(Self { - kernel_core, + /// 创建 VM 池并同步预热 `min_size` 个 Vm(数量受 `max_size` 钳制), + /// 首次 `spawn` 直接命中池。`max_size` 为池上限,`None` 表示不限。 + pub fn new(kernel_core: Arc, min_size: usize, max_size: Option) -> Arc { + let warm = min_size.min(max_size.unwrap_or(min_size)); + let pool = Arc::new(Self { + kernel_core: Arc::clone(&kernel_core), inner: Mutex::new(VmPoolInner { available: Vec::new(), total_count: 0, }), condvar: Condvar::new(), max_size, - }) + }); + let mut inner = pool.inner.lock().unwrap(); + for _ in 0..warm { + inner.available.push(Self::new_vm(&kernel_core)); + inner.total_count += 1; + } + drop(inner); + pool } fn new_vm(core: &Arc) -> Vm { @@ -173,4 +182,32 @@ mod tests { drop(g1); drop(g2); } + + #[test] + fn test_pool_warms_min_size_on_new() { + let kernel = test_kernel(); + let pool = VmPool::new(kernel, 2, None); + { + let inner = pool.inner.lock().unwrap(); + assert_eq!(inner.available.len(), 2); + assert_eq!(inner.total_count, 2); + } + let g1 = pool.spawn(); + let g2 = pool.spawn(); + { + let inner = pool.inner.lock().unwrap(); + assert_eq!(inner.total_count, 2); + } + drop(g1); + drop(g2); + } + + #[test] + fn test_pool_warmup_clamped_by_max_size() { + let kernel = test_kernel(); + let pool = VmPool::new(kernel, 2, Some(1)); + let inner = pool.inner.lock().unwrap(); + assert_eq!(inner.available.len(), 1); + assert_eq!(inner.total_count, 1); + } }