%% SCRAP: architecture/03-architecture/pipelining/phase-1-instrumentation
%% SOURCE: docs/working/architecture/03-architecture/pipelining/phase-1-instrumentation.md
%% STATUS: WORKING
%% FITS: dev-guide/ch-pipelining
%% EDITORIAL: lifted — prose rewritten to press voice

\section{Phase 1: Pipelining Instrumentation}

Phase~1 establishes the observability layer for pipelining: it tracks
word-to-word transitions during execution to answer which words typically
follow which. It deliberately stops short of speculative execution, collecting
the data that later phases will act upon.

\subsection{Transition Metrics Structure}

Each dictionary word carries a pointer to a transition-metrics record holding
the per-successor transition-heat array, a total count, prefetch counters
reserved for Phase~3, \Qtype{} latency accounts, and a cached most-likely
successor with its probability.

\begin{lstlisting}[language=C]
typedef struct WordTransitionMetrics {
    uint64_t *transition_heat;               /* Array[DICTIONARY_SIZE] */
    uint64_t  total_transitions;
    uint64_t  prefetch_attempts;             /* Phase 3 */
    uint64_t  prefetch_hits;                 /* Phase 3 */
    uint64_t  prefetch_misses;               /* Phase 3 */
    int64_t   prefetch_latency_saved_q48;    /* Phase 3 */
    int64_t   misprediction_cost_q48;        /* Phase 3 */
    int64_t   max_transition_probability_q48;
    uint32_t  most_likely_next_word_id;
} WordTransitionMetrics;
\end{lstlisting}

The transition-heat array is allocated lazily on the first transition, so words
that never execute consume no memory for tracking.

\subsection{Data Collection}

The inner interpreter records one transition per word boundary, gated on
\lstinline{ENABLE_PIPELINING}. The cost is about two cycles per word
execution---lost in the noise of the word itself.

\begin{lstlisting}[language=C]
if (prev_word && prev_word->transition_metrics && ENABLE_PIPELINING) {
    transition_metrics_record(prev_word->transition_metrics,
                              word_id, DICTIONARY_SIZE);
}
\end{lstlisting}

\subsection{Fixed-Point Probability}

All probabilities use 64-bit signed \Qtype{} fixed point, which keeps the math
deterministic across platforms, free of \texttt{libm}, and compatible with
formal verification---no floating point appears on the path.

\begin{equation}
  P_{\text{Q48.16}}
  = \frac{\mathtt{transition\_heat}[\text{target}] \ll 16}
         {\mathtt{total\_transitions}}.
\end{equation}

For example, 85 of 100 successors gives $(85 \ll 16)/100 = \mathtt{0xD800}$,
i.e.\ $0.828125$, an $82.8\%$ probability.

\subsection{Tuning Knobs}

Five parameters control speculation behavior in later phases:
\lstinline{SPECULATION_THRESHOLD_Q48} (default $0.50$, minimum confidence),
\lstinline{SPECULATION_DEPTH} (default $1$, words ahead),
\lstinline{MIN_SAMPLES_FOR_SPECULATION} (default $10$, observations before
trusting a pattern), \lstinline{MISPREDICTION_COST_Q48} (default $25$~ns,
recovery cost), and \lstinline{MINIMUM_PREFETCH_ROI} (default $1.10$, required
improvement).

\subsection{Diagnostic Words}

Six FORTH words inspect the collected metrics:

\begin{lstlisting}[language=Forth]
PIPELINING-STATS                  ( -- )         \ dictionary-wide aggregate
PIPELINING-SHOW-STATS             ( addr len -- ) \ one word's metrics
PIPELINING-SHOW-TOP-TRANSITIONS   ( addr len N -- ) \ top N successors
PIPELINING-ANALYZE-WORD           ( addr len -- ) \ predictability assessment
PIPELINING-RESET-ALL              ( -- )         \ clear all metrics
PIPELINING-ENABLE                 ( -- )         \ report compile-time state
\end{lstlisting}

Hot words such as \texttt{EXIT}, \texttt{LIT}, \texttt{DUP}, \texttt{@}, and
\texttt{!} show hundreds to thousands of transitions with strong preferred
successors, while rare words show few, variable transitions and make poor
speculation candidates.

\subsection{Design Decisions}

\begin{itemize}
  \item \textbf{Lazy allocation.} Most words execute rarely; allocating a
        full-width array for every word would waste memory, so allocation is
        deferred to first use.
  \item \textbf{Fixed point over floating point.} Double precision was rejected
        because it breaks formal verification on L4Re, accumulates error over
        long benchmarks, and rounds platform-dependently.
  \item \textbf{Pointer rather than embedded struct.} A pointer permits lazy
        allocation and optional compilation without enlarging every dictionary
        entry.
\end{itemize}

\subsection{Status and Known Limits}

Phase~1 is complete: instrumentation collects transitions automatically,
diagnostics report them, the build is non-breaking, and the test suite passes.
Default builds collect but do not act on the data
(\lstinline{ENABLE_PIPELINING=0}). Known limitations are an
$O(\text{DICTIONARY\_SIZE})$ linear scan for word-ID lookup on each transition
(a Phase~2 target, addressable with a \lstinline{word_id} field for an
estimated hundred-fold speedup), non-atomic recording unsuited to multiple
threads, and manual, non-adaptive knob tuning.

%% TODO(bob): the source cites "all 731 tests passing"; the current suite is
%% 936+. Confirm the test count appropriate to this chapter's vintage.
