# FerroRisk benchmark snapshot — 9 September 2026

FerroRisk **0.38.2, unreleased M1 development snapshot**, source revision
`c8078b72e5c1e9ae64b7e8243c7ccf91e162aa5c`.

These measurements cover the M1 American kernels integrated for 0.38.4. An
[untimed replay on the 0.38.4 source build](release-check.json), revision
`301f5d0a4dadfcd00defebc805366afa66fd36cd`, reproduces identical input and result
records for all nine published fixtures, with zero allocations in the scalar
probes. This replay does not measure 0.38.4 latency: the timings below retain
their original build identity and conditions.

These are successful scalar engine operations on specific fixtures. They are
not service latency, a 100K batch measurement, a QuantLib comparison, or a
claim that every input has the same cost or admits a complete Greek vector.

## Results and source identity

- [summary.json](summary.json): the published phase medians, input bits,
  workload identities, units, compiler, lockfile and binary identities.
- [raw-results.json](raw-results.json): both baseline phases' unmodified
  Criterion samples, estimates and workload records for all nine table rows,
  plus before/after result observations and allocation probes collected outside timing.
- [m1_exit_perf.rs](m1_exit_perf.rs): the exact original 55-workload harness.
- [frozen-quotes.tsv](frozen-quotes.tsv): the original frozen quote roles,
  consumed unchanged by the harness. These model-generated quotes are timing
  inputs, not independent accuracy oracles.

The measured source is in the access-controlled repository
`https://gitlab.com/prophetizo/morphiq-labs/core/ferro-risk`. Source access is
required to rebuild the engine; this public evidence bundle does not contain
the engine source or grant access to it.

The full experiment ran A1/B1/B2/A2 over 55 workloads, with an experimental
forced-inline build in the B phases. That experiment missed its improvement
target. The page publishes only the unchanged M1 baseline's A1 and A2 phases.
The original benchmark executable SHA-256 is
`518e05ab30ed6e79a4a76207cccbfabb37c7e57b1bebe65d23e344f416044f9b`.

## Method

- Apple M1 Pro, 10 cores, MacBookPro18,1, 16 GiB; macOS 26.6.2.
- Rust/Cargo 1.97.1, Cargo `bench` profile, default + SIMD features.
- Single-threaded scalar operations; `RAYON_NUM_THREADS=4` for the surrounding
  harness, which also contains separate batch workloads.
- 60 Criterion samples, one-second warmup, at least three seconds of timing
  per workload per phase. Input construction and output formatting are outside
  timing. Allocation probes run separately, five times with 100 calls per probe.
- Each table interval is the minimum and maximum of the two **phase medians**.
  Each card rounds their arithmetic midpoint to the displayed precision. An
  interval across two phase medians is not an overall confidence interval.
- Timing ran from 16:30:47 to 16:47:39 UTC on AC power with normal OS/application
  work. The host owner requested immediate measurement without CPU admission
  limits. Of 200 host observations, 43 exceeded an original CPU screen. No
  compiler/reference/fuzz worker or thermal/performance warning was recorded.
  Die temperature was not measured. Repeatability and independent arithmetic
  controls passed the experiment's 5% drift screen; this does not establish an
  isolated host or an absolute release budget.

## Timed operations and inputs

Pricing calls use the direct `bsm_price`, `black76_price`, or `american_price`
function. Greek calls use `ResolvedGreekRequest::greeks`; request construction
and validation are outside those timings. IV calls use `implied_vol` with a
frozen model-generated price. All table entries have one contract per call.

| Fixture | Type | Spot / forward | Strike | Expiry (years) | Rate | Yield | Volatility |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| European | Call | 120 | 100 | 0.75 | 0.03 | 0.01 | 0.32 |
| Black-76 | Call | 4900 | 5000 | 0.5 | 0.045 | 0 | 0.27 |
| American | Call | 100 | 100 | 1 | 0.05 | 0.03 | 0.30 |
| American | Put | 100 | 105 | 0.5 | 0.03 | 0.01 | 0.25 |

European pricing and IV use Black-Scholes-Merton; American uses
**Bjerksund-Stensland 2002**. No discrete cash-dividend schedule is supplied in
these rows. Rates are continuously compounded decimal fractions. Price uses
the input monetary unit. The ten Greeks are delta, gamma, theta, vega, rho,
vanna, volga, charm, veta and color. Time sensitivities theta/charm/veta/color
are per calendar day; vega and rho are per unit volatility/rate, not per
volatility point or basis point. Exact input and quote bits are retained.
American Greeks combine dual derivatives with a separate time stencil for
color. Nonsmooth contacts can make a complete vector unavailable; those
outcomes are typed errors, not a claim of global analytical availability.

## Reproduction

Use a clean checkout of the source revision above, its committed lockfile and
pinned toolchain. Download this directory's harness and frozen quotes. Add
the harness as `crates/ferro-risk/benches/m1_exit_perf.rs` and append this
benchmark-only entry to that package's `Cargo.toml`:

```toml
[[bench]]
name = "m1_exit_perf"
harness = false
```

Build before observing your measurement window. Set `CARGO_TARGET_DIR` to a
fresh directory so existing evidence is preserved. From the workspace root:

```sh
RAYON_NUM_THREADS=4 cargo rustc --locked -p ferro-risk --bench m1_exit_perf \
  --profile bench --message-format=json-render-diagnostics -- \
  --check-cfg 'cfg(candidate_report)' --cfg candidate_report > build.jsonl
```

Use the `executable` from the `m1_exit_perf` compiler-artifact record in
`build.jsonl`. The `candidate_report` cfg only enables the harness's price-report
workload; it does not change library compilation. Set `FERRO_PERF_QUOTES` to
the absolute path of `frozen-quotes.tsv` and `RAYON_NUM_THREADS=4` before every
invocation. The executable supports `--catalog`, `--preflight` and
`--allocations` without enabling timing. Retain these observations first.

For each timing phase, set `CRITERION_HOME` to a **new, empty, exclusive**
directory, then execute the prebuilt binary with:

```sh
FERRO_M1_PERF_RUN=1 /absolute/path/to/m1_exit_perf \
  --bench --noplot --sample-size 60 --measurement-time 3 --warm-up-time 1
```

Run `--preflight` again after each phase and compare with the initial results.
Repeat with the same executable and fresh output directories to check drift.
Preserve hardware, power, background-activity and build records. Do not compile
or run other numerical work during timing. The complete harness includes
specialized 10K batch and refused-input cases; those are not the successful
scalar results on the webpage. Do not extrapolate them to a 100K workload.

Within the website repository, `npm run check:benchmarks` independently computes
medians from the retained sample times and iteration counts, checks the
displayed figures and allocation probes, and verifies raw-data/harness hashes.
The production build runs this check before generating the static site.
