Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure
Source tree reorganization: - Move StarForth v3 engine to v3/ (src/, include/, Makefile) - Move kernel to kernel/ (src/, include/, linker/, Makefile) - Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md) - Move FABRIC-0..4.md to docs/fabric/ - Move ONTOLOGY.md and ROADMAP.md to docs/ Board infrastructure: - Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/ - Each board has board.mk (ISA, CPU flags, boot recipe) and README.md - Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET - make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board - ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet) - scripts/mkdiskimage.sh builds disk images for all boards Docs pipeline: - docs/book/ with LaTeX master (main.tex) and Makefile - pandoc converts Markdown to LaTeX at build time - Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks) - make docs builds single PDF (754 pages, 0 missing characters) - make docs TARGET=<board> adds board appendix - build/docs/<book|board>/meta.tex stamps git commit into PDF Bug fixes: - 42 include paths that only worked by accident now use correct relative paths - clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build) - Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved - Doxyfile, .clang-tidy, README.md, Kconfig paths updated Verified: - Hosted v3 build passes 1012 tests, 0 failures - SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE) - Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes - make clean TARGET=<board> removes only that board and its ISA objects - make all builds all boards, hosted v3, and docs in one run Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
StarForth — Steady-State Virtual Machine Runtime
|
||||
|
||||
Copyright (c) 2023–2025 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) 2023–2025 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 */
|
||||
Reference in New Issue
Block a user