Files
LithosAnanake/docs/formal/scraps/architecture/03-architecture/heartbeat-system/architecture.tex
T

149 lines
5.5 KiB
TeX

%% SCRAP: architecture/03-architecture/heartbeat-system/architecture
%% SOURCE: docs/working/architecture/03-architecture/heartbeat-system/architecture.md
%% STATUS: WORKING
%% FITS: dev-guide/ch-heartbeat
%% EDITORIAL: lifted — prose rewritten to press voice
\subsection{Heartbeat Architecture: Centralised Time-Based Tuning}
The heartbeat mechanism coordinates all time-driven VM operations through a
single dispatcher, \texttt{vm\_tick()}. Both Loop~\#5 (rolling-window tuning)
and Loop~\#3 (heat-decay validation) are time-driven events that belong in one
place rather than scattered through execution paths. The same dispatcher is
designed to evolve into a background thread for system observability without
touching core VM logic.
\subsubsection{HeartbeatState}
The \texttt{HeartbeatState} struct, declared in \texttt{include/vm.h} and
embedded in the \texttt{VM} struct, holds the tick counter and per-plugin
cursors:
\begin{lstlisting}[language=C]
typedef struct {
uint64_t tick_count; /* total ticks since VM init */
uint64_t last_window_tune_tick; /* tick of last window tune */
uint64_t last_slope_tune_tick; /* tick of last decay validation */
int heartbeat_enabled; /* 1 = active, 0 = disabled */
} HeartbeatState;
\end{lstlisting}
\subsubsection{Dispatcher}
\texttt{vm\_tick()} in \texttt{src/vm.c} increments the global tick counter and
dispatches each plugin at its configured interval:
\begin{lstlisting}[language=C]
void vm_tick(VM *vm)
{
if (!vm || !vm->heartbeat.heartbeat_enabled)
return;
vm->heartbeat.tick_count++;
/* Plugin 1: Window Tuning (Loop #5) */
if (ENABLE_PIPELINING &&
(vm->heartbeat.tick_count
- vm->heartbeat.last_window_tune_tick) >= WINDOW_TUNING_FREQUENCY)
{
vm_tick_window_tuner(vm);
vm->heartbeat.last_window_tune_tick = vm->heartbeat.tick_count;
}
/* Plugin 2: Heat Decay Slope Validation (Loop #3) */
if ((vm->heartbeat.tick_count
- vm->heartbeat.last_slope_tune_tick) >= SLOPE_VALIDATION_FREQUENCY)
{
vm_tick_slope_validator(vm);
vm->heartbeat.last_slope_tune_tick = vm->heartbeat.tick_count;
}
}
\end{lstlisting}
\subsubsection{Window Tuner Plugin}
\texttt{vm\_tick\_window\_tuner()} in \texttt{src/physics\_pipelining\_metrics.c}
computes the current prefetch accuracy and delegates to
\texttt{loop\_5\_binary\_chop\_suggest\_window()} for the next candidate size:
\begin{lstlisting}[language=C]
void vm_tick_window_tuner(VM *vm)
{
RollingWindowOfTruth *window = &vm->rolling_window;
PipelineGlobalMetrics *metrics = &vm->pipeline_metrics;
if (!window->is_warm || metrics->prefetch_attempts == 0)
return;
double accuracy = (double)metrics->prefetch_hits
/ (double)metrics->prefetch_attempts;
uint32_t suggested = loop_5_binary_chop_suggest_window(
metrics,
window->effective_window_size,
ADAPTIVE_MIN_WINDOW_SIZE,
ROLLING_WINDOW_SIZE);
if (suggested != window->effective_window_size)
window->effective_window_size = suggested;
metrics->last_checked_window_size = window->effective_window_size;
metrics->last_checked_accuracy = accuracy;
metrics->window_tuning_checks++;
}
\end{lstlisting}
\subsubsection{Slope Validator Plugin}
\texttt{vm\_tick\_slope\_validator()} in \texttt{src/physics\_metadata.c}
scans the dictionary and classifies entries by execution heat, using execution
frequency as a proxy for thermal energy. It logs the hot-word count, the
stale-word ratio, and the mean heat, providing the raw signal needed to assess
whether the linear decay function is removing cache pollution at the right rate.
A follow-on phase will compare the stale-word ratio trend over consecutive ticks
to decide whether a different decay function (exponential, logarithmic) would
converge faster.
\subsubsection{Integration into the Execution Path}
Two integration modes are supported.
\textbf{Synchronous (current default).} The main interpreter increments an
execution counter and fires \texttt{vm\_tick()} every \texttt{HEARTBEAT\_FREQUENCY}
word executions:
\begin{lstlisting}[language=C]
if (++vm->execution_count % HEARTBEAT_FREQUENCY == 0)
vm_tick(vm);
\end{lstlisting}
This adds negligible latency as long as plugin work remains lightweight.
\textbf{Background thread (future).} When \texttt{HEARTBEAT\_THREAD\_ENABLED=1},
a POSIX thread wakes at \texttt{HEARTBEAT\_INTERVAL\_MS} and calls
\texttt{vm\_tick()} independently of the execution hot-path. State shared
between threads must be protected by \texttt{vm->tuning\_lock}.
\subsubsection{Configuration Knobs}
\begin{tabular}{lll}
\toprule
Knob & Default & Meaning \\
\midrule
\texttt{HEARTBEAT\_FREQUENCY} & 256 & Executions between ticks \\
\texttt{WINDOW\_TUNING\_FREQUENCY} & 1000 & Ticks between window-tuner calls \\
\texttt{SLOPE\_VALIDATION\_FREQUENCY}& 5000 & Ticks between decay validations \\
\texttt{HEARTBEAT\_THREAD\_ENABLED} & 0 & 1 = background thread \\
\texttt{HEARTBEAT\_THREAD\_INTERVAL\_MS} & 100 & Thread wake interval (ms) \\
\bottomrule
\end{tabular}
\subsubsection{Code Locations}
\begin{itemize}
\item \texttt{include/vm.h} --- \texttt{HeartbeatState} struct; \texttt{vm\_tick()} prototype
\item \texttt{src/vm.c} --- \texttt{vm\_tick()} dispatcher; execution-path integration
\item \texttt{src/physics\_pipelining\_metrics.c} --- \texttt{vm\_tick\_window\_tuner()}
\item \texttt{src/physics\_metadata.c} --- \texttt{vm\_tick\_slope\_validator()}
\end{itemize}