[PERF] Runtime Telemetry Hot Path

This commit is contained in:
bQUARKz 2026-04-10 09:20:07 +01:00
parent 698a076632
commit e672e4d6b6
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 28 additions and 21 deletions

View File

@ -17,10 +17,17 @@ use std::sync::{Arc, Mutex, RwLock};
use std::thread; use std::thread;
use std::time::Instant; use std::time::Instant;
type ResidentMap<T> = HashMap<AssetId, ResidentEntry<T>>;
type StagedValue<T> = (Arc<T>, usize);
type StagingMap<T> = HashMap<HandleId, StagedValue<T>>;
type AssetTable = HashMap<AssetId, AssetEntry>;
type HandleTable = HashMap<HandleId, LoadHandleInfo>;
const GLYPH_BANK_PALETTE_COUNT_V1: usize = 64; const GLYPH_BANK_PALETTE_COUNT_V1: usize = 64;
const GLYPH_BANK_COLORS_PER_PALETTE: usize = 16; const GLYPH_BANK_COLORS_PER_PALETTE: usize = 16;
const GLYPH_BANK_PALETTE_BYTES_V1: usize = const GLYPH_BANK_PALETTE_BYTES_V1: usize =
GLYPH_BANK_PALETTE_COUNT_V1 * GLYPH_BANK_COLORS_PER_PALETTE * std::mem::size_of::<u16>(); GLYPH_BANK_PALETTE_COUNT_V1 * GLYPH_BANK_COLORS_PER_PALETTE * size_of::<u16>();
/// Resident metadata for a decoded/materialized asset inside a BankPolicy. /// Resident metadata for a decoded/materialized asset inside a BankPolicy.
#[derive(Debug)] #[derive(Debug)]
@ -54,10 +61,10 @@ impl<T> ResidentEntry<T> {
/// This is internal to the AssetManager and not visible to peripherals. /// This is internal to the AssetManager and not visible to peripherals.
pub struct BankPolicy<T> { pub struct BankPolicy<T> {
/// Dedup table: asset_id -> resident entry (value + telemetry). /// Dedup table: asset_id -> resident entry (value + telemetry).
pub resident: Arc<RwLock<HashMap<AssetId, ResidentEntry<T>>>>, pub resident: Arc<RwLock<ResidentMap<T>>>,
/// Staging area: handle -> value ready to commit. /// Staging area: handle -> value ready to commit.
pub staging: Arc<RwLock<HashMap<HandleId, (Arc<T>, usize)>>>, pub staging: Arc<RwLock<StagingMap<T>>>,
/// Total bytes currently in resident storage. /// Total bytes currently in resident storage.
pub used_bytes: Arc<AtomicUsize>, pub used_bytes: Arc<AtomicUsize>,
@ -119,7 +126,7 @@ impl<T> BankPolicy<T> {
} }
/// Take staged value (used by commit path). /// Take staged value (used by commit path).
pub fn take_staging(&self, handle: HandleId) -> Option<(Arc<T>, usize)> { pub fn take_staging(&self, handle: HandleId) -> Option<StagedValue<T>> {
let entry = self.staging.write().unwrap().remove(&handle); let entry = self.staging.write().unwrap().remove(&handle);
if let Some((_, bytes)) = entry.as_ref() { if let Some((_, bytes)) = entry.as_ref() {
self.inflight_bytes.fetch_sub(*bytes, Ordering::Relaxed); self.inflight_bytes.fetch_sub(*bytes, Ordering::Relaxed);
@ -136,8 +143,8 @@ impl<T> BankPolicy<T> {
} }
pub struct AssetManager { pub struct AssetManager {
assets: Arc<RwLock<HashMap<AssetId, AssetEntry>>>, assets: Arc<RwLock<AssetTable>>,
handles: Arc<RwLock<HashMap<HandleId, LoadHandleInfo>>>, handles: Arc<RwLock<HandleTable>>,
next_handle_id: Mutex<HandleId>, next_handle_id: Mutex<HandleId>,
assets_data: Arc<RwLock<AssetsPayloadSource>>, assets_data: Arc<RwLock<AssetsPayloadSource>>,
@ -476,7 +483,11 @@ impl AssetManager {
bank_arc, bank_arc,
entry_clone.decoded_size as usize, entry_clone.decoded_size as usize,
); );
gfx_policy.stage(handle_id, resident_arc, entry_clone.decoded_size as usize); gfx_policy.stage(
handle_id,
resident_arc,
entry_clone.decoded_size as usize,
);
let mut handles_map = handles.write().unwrap(); let mut handles_map = handles.write().unwrap();
if let Some(h) = handles_map.get_mut(&handle_id) { if let Some(h) = handles_map.get_mut(&handle_id) {
@ -500,8 +511,11 @@ impl AssetManager {
bank_arc, bank_arc,
entry_clone.decoded_size as usize, entry_clone.decoded_size as usize,
); );
sound_policy sound_policy.stage(
.stage(handle_id, resident_arc, entry_clone.decoded_size as usize); handle_id,
resident_arc,
entry_clone.decoded_size as usize,
);
let mut handles_map = handles.write().unwrap(); let mut handles_map = handles.write().unwrap();
if let Some(h) = handles_map.get_mut(&handle_id) { if let Some(h) = handles_map.get_mut(&handle_id) {

View File

@ -10,12 +10,7 @@ pub struct LogService {
impl LogService { impl LogService {
pub fn new(capacity: usize) -> Self { pub fn new(capacity: usize) -> Self {
Self { Self { events: VecDeque::with_capacity(capacity), capacity, next_seq: 0, logs_count: 0 }
events: VecDeque::with_capacity(capacity),
capacity,
next_seq: 0,
logs_count: 0,
}
} }
pub fn log( pub fn log(

View File

@ -180,10 +180,7 @@ impl Certifier {
LogLevel::Warn, LogLevel::Warn,
LogSource::Pos, LogSource::Pos,
0xCA07, 0xCA07,
format!( format!("Cert: Log pressure exceeded limit ({} > {})", telemetry.logs_count, limit),
"Cert: Log pressure exceeded limit ({} > {})",
telemetry.logs_count, limit
),
); );
violations += 1; violations += 1;
} }

View File

@ -149,7 +149,8 @@ impl VirtualMachineRuntime {
self.telemetry_current.logs_count = self.log_service.logs_count; self.telemetry_current.logs_count = self.log_service.logs_count;
self.log_service.reset_count(); self.log_service.reset_count();
self.telemetry_current.host_cpu_time_us = start.elapsed().as_micros() as u64; self.telemetry_current.host_cpu_time_us =
start.elapsed().as_micros() as u64;
let ts_ms = self.boot_time.elapsed().as_millis() as u64; let ts_ms = self.boot_time.elapsed().as_millis() as u64;
self.telemetry_current.violations = self.certifier.evaluate( self.telemetry_current.violations = self.certifier.evaluate(

View File

@ -2,8 +2,8 @@ use crate::call_frame::CallFrame;
use crate::object::{ObjectHeader, ObjectKind}; use crate::object::{ObjectHeader, ObjectKind};
use prometeu_bytecode::{HeapRef, Value}; use prometeu_bytecode::{HeapRef, Value};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
/// Internal stored object: header plus opaque payload bytes. /// Internal stored object: header plus opaque payload bytes.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]