Files
LithosAnanake/include/physics_hotwords_cache.h
T

314 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* physics_hotwords_cache.h
*
* Hot-words cache optimization: frequency-driven dictionary acceleration
*
* Compile-time switch to enable/disable the hot-words cache variant.
* Allows measuring impact before/after on different build profiles.
*
* Usage:
* make clean && make ENABLE_HOTWORDS_CACHE=1 # With cache
* make clean && make ENABLE_HOTWORDS_CACHE=0 # Without cache
*
* Measure performance:
* BENCH-DICT-LOOKUP (show baseline + stats)
* PHYSICS-SHOW-CACHE-STATS (show hit rate, evictions, etc)
*/
#ifndef PHYSICS_HOTWORDS_CACHE_H
#define PHYSICS_HOTWORDS_CACHE_H
#include <stdint.h>
#include "vm.h"
/* ============================================================================
* Feature Switch
* ============================================================================
*
* Set via -DENABLE_HOTWORDS_CACHE=1 during compilation
* Default: enabled (can be disabled for baseline comparison)
*/
#ifndef ENABLE_HOTWORDS_CACHE
#define ENABLE_HOTWORDS_CACHE 1
#endif
/* ============================================================================
* Hot Words Cache Configuration
* ============================================================================
*/
/** Maximum number of hot words to cache (typically 16-32) */
#define HOTWORDS_CACHE_SIZE 32
/** Execution heat threshold to consider a word "hot" (execution count) */
#define HOTWORDS_EXECUTION_HEAT_THRESHOLD 50
/** Reorder bucket when execution heat delta exceeds this (avoid thrashing) */
#define HOTWORDS_EXECUTION_HEAT_DELTA_THRESHOLD 100
/* ============================================================================
* Statistics Structure
* ============================================================================
*
* Tracks cache performance for measurement and diagnostics
*/
typedef struct {
/** Total lookups performed */
uint64_t total_lookups;
/** Lookups that hit the hot-words cache */
uint64_t cache_hits;
/** Lookups that missed cache but found in bucket */
uint64_t bucket_hits;
/** Lookups that failed (word not found) */
uint64_t misses;
/** Words evicted from cache (LRU) */
uint64_t evictions;
/** Times a word was promoted to hot-words */
uint64_t promotions;
/** Times bucket was reordered */
uint64_t bucket_reorders;
/** === 64-bit Fixed-Point Statistics (Q48.16 format) ===
* Q48.16 = 48-bit integer + 16-bit fractional part
* Precision: 2^-16 ns ≈ 0.0000153 ns
* Range: ±140 trillion ns (≈ 4.4 years)
* Allows: Bayesian inference, precise averaging, statistical computation
*/
/** Sum of cache hit latencies (64-bit fixed-point, Q48.16) */
int64_t cache_hit_total_ns_q48;
/** Sum of bucket search latencies (64-bit fixed-point, Q48.16) */
int64_t bucket_search_total_ns_q48;
/** Number of cache hit samples (for averaging) */
uint64_t cache_hit_samples;
/** Number of bucket search samples (for averaging) */
uint64_t bucket_search_samples;
/** Minimum cache hit latency (nanoseconds) */
int64_t min_cache_hit_ns;
/** Maximum cache hit latency (nanoseconds) */
int64_t max_cache_hit_ns;
/** Minimum bucket search latency (nanoseconds) */
int64_t min_bucket_search_ns;
/** Maximum bucket search latency (nanoseconds) */
int64_t max_bucket_search_ns;
/** Sum of squared cache hit latencies (for variance/stddev) */
int64_t cache_hit_variance_sum_q48;
/** Sum of squared bucket search latencies (for variance/stddev) */
int64_t bucket_search_variance_sum_q48;
} HotwordsStats;
/* ============================================================================
* Hot Words Cache State
* ============================================================================
*
* Embedded in VM for global state
*/
typedef struct HotwordsCache_s {
/** Cache entries (pointers to DictEntry) */
DictEntry *cache[HOTWORDS_CACHE_SIZE];
/** Number of valid entries in cache */
uint32_t cache_count;
/** LRU: last-used index for eviction */
uint32_t lru_index;
/** Performance statistics */
HotwordsStats stats;
/** Enabled/disabled flag (runtime toggle) */
int enabled;
} HotwordsCache;
/* ============================================================================
* Public API
* ============================================================================
*/
/**
* Initialize hot-words cache
* Should be called during VM initialization
*/
void hotwords_cache_init(HotwordsCache *cache);
/**
* Cleanup hot-words cache
*/
void hotwords_cache_cleanup(HotwordsCache *cache);
/**
* Lookup word in cache first, then fall back to bucket search
* Returns the found word, or NULL if not found
*
* This is the main function that replaces vm_find_word() logic.
* Takes the VM so the bucket fallback can resolve same-named entries by
* definition age (vm_dict_resolve_in_bucket) — bucket order alone is not
* authoritative once dict_reorganize_buckets_by_heat() has run.
*/
DictEntry *hotwords_cache_lookup(VM *vm,
HotwordsCache *cache,
DictEntry **bucket,
size_t bucket_count,
const char *name,
size_t len);
/**
* Promote a word to the hot-words cache
* Called when a word's execution heat exceeds threshold
*/
void hotwords_cache_promote(HotwordsCache *cache, DictEntry *word);
/**
* Evict every cache slot holding this exact entry.
* Must be called before an entry is freed (FORGET) — a stale pointer in the
* ring is a use-after-free.
*/
void hotwords_cache_evict_entry(HotwordsCache *cache, const DictEntry *word);
/**
* Evict every cache slot whose entry matches this name.
* Called whenever name resolution may change: word creation (shadowing),
* smudge/unsmudge, hide. The next lookup re-resolves through the bucket.
*/
void hotwords_cache_evict_name(HotwordsCache *cache, const char *name, size_t len);
/**
* Reorder a bucket by execution heat (move hot words forward)
* Called when execution heat delta exceeds threshold
*/
void hotwords_bucket_reorder(DictEntry **bucket, size_t count);
/**
* Reset statistics (for before/after comparison)
*/
void hotwords_stats_reset(HotwordsStats *stats);
/**
* Print statistics to stdout
*/
void hotwords_stats_print(const HotwordsStats *stats);
/**
* Enable/disable cache at runtime (for A/B testing)
*/
void hotwords_cache_set_enabled(HotwordsCache *cache, int enabled);
/* ============================================================================
* Bayesian Inference Statistics
* ============================================================================
*/
/**
* Bayesian statistics structure for inference and credible intervals
* All values stored in Q48.16 fixed-point (64-bit signed integer)
* representing nanoseconds with 2^-16 ≈ 0.0000153 ns precision
*/
typedef struct {
int64_t mean_ns_q48; /* Mean latency (Q48.16) */
int64_t stddev_ns_q48; /* Standard deviation (Q48.16) */
int64_t median_ns_q48; /* Median (p50) (Q48.16) */
int64_t credible_lower_95; /* Lower bound of 95% credible interval (Q48.16) */
int64_t credible_upper_95; /* Upper bound of 95% credible interval (Q48.16) */
int64_t credible_lower_99; /* Lower bound of 99% credible interval (Q48.16) */
int64_t credible_upper_99; /* Upper bound of 99% credible interval (Q48.16) */
uint64_t sample_count; /* Number of samples in posterior */
} BayesianLatencyPosterior;
/**
* Calculate posterior distribution for cache hits
* Uses accumulated samples to compute credible intervals
*/
BayesianLatencyPosterior hotwords_posterior_cache_hits(const HotwordsStats *stats);
/**
* Calculate posterior distribution for bucket searches
* Uses accumulated samples to compute credible intervals
*/
BayesianLatencyPosterior hotwords_posterior_bucket_searches(const HotwordsStats *stats);
/**
* Calculate speedup estimate with credible interval
* All values in Q48.16 fixed-point format (64-bit signed integer)
* Probabilities are in range [0, Q48_SCALE] representing [0%, 100%]
*/
struct SpeedupEstimate {
int64_t speedup_factor_q48; /* Bucket latency / Cache latency (Q48.16) */
int64_t credible_lower_95_q48; /* Lower bound (95% credible) (Q48.16) */
int64_t credible_upper_95_q48; /* Upper bound (95% credible) (Q48.16) */
int64_t probability_gt_10pct_q48; /* P(speedup > 1.1) in Q48.16, [0, 65536] = [0%, 100%] */
int64_t probability_gt_double_q48;/* P(speedup > 2.0) in Q48.16, [0, 65536] = [0%, 100%] */
};
/**
* Calculate speedup estimate with uncertainty
*/
struct SpeedupEstimate hotwords_speedup_estimate(const HotwordsStats *stats);
/**
* Generate detailed Bayesian inference report
* Compares cache vs bucket performance with confidence measures
*/
void hotwords_bayesian_report(const HotwordsStats *stats_with_cache,
const HotwordsStats *stats_without_cache);
#endif /* PHYSICS_HOTWORDS_CACHE_H */