Skip to content

kernel: store the conversion cache as flat integer arrays - #22319

Draft
JasonGross wants to merge 2 commits into
rocq-prover:masterfrom
theorem-labs:codex/conversion-cache-flat-arrays
Draft

kernel: store the conversion cache as flat integer arrays#22319
JasonGross wants to merge 2 commits into
rocq-prover:masterfrom
theorem-labs:codex/conversion-cache-flat-arrays

Conversation

@JasonGross

Copy link
Copy Markdown
Member

Summary

This is a stacked follow-up to #22309. It replaces the conversion cache's Hashtbl of boxed entries with two flat integer arrays using open addressing.

Please review #22309 first. The first commit in this draft is exactly that PR's current head; the new change is the second commit, kernel: store the conversion cache as flat integer arrays. Once #22309 lands, this PR can be rebased to contain only the latter.

Motivation

On the motivating Bonak check, the cache can grow to roughly 60 million entries in one conversion session. With boxed tuples and hash-table bucket lists, those entries become a substantial allocation and major-GC tracing cost.

Each entry is representable by two machine integers after lift values are interned:

  • one integer packs the pair of closure cell IDs;
  • one integer packs the interned lift IDs, conversion problem kind, and cached result.

The replacement table uses linear probing and doubles on growth. It allocates no object per entry, and its integer arrays do not add pointer fields for the GC to trace.

Performance evidence

The motivating heavy check retained identical probe, hit, and insertion counts digit-for-digit. Relative to the boxed cache in #22309, the flat representation reportedly gave a further approximately 2.6x runtime improvement and reduced peak memory by about one third.

This draft does not claim to solve all memory concerns noted on #22309: in particular, it does not remove the additional ID field from fconstr. It specifically reduces the cache table's representation overhead.

Validation

  • opam exec --switch=rocq-dev-testing -- dune build kernel/kernel.cma
  • opam exec --switch=rocq-dev-testing -- dune runtest kernel

Both pass locally.

Authorship note: this was researched and written by an AI coding agent (OpenAI Codex), working on Jason Gross's behalf; Jason reviews what is posted from this account.

A telescope-heavy kernel check compares the same pair of closures over and
over: beta-substitution shares payload cells across every occurrence of a
variable, so the same two cells meet again at each copy of the term they
were substituted into. The reduction machine has no memory of this and
re-derives each convertibility subproblem from scratch.

Give each fconstr cell a stable id (a new lazily-assigned mutable field,
preserved by the in-place [update] the machine uses for reduction and
reset on every copy), and add a per-session table in `ccnv` mapping a pair
of cell ids plus lift pair and conversion problem to the outcome
(convertible or not). On a hit the outcome is replayed directly; both
successes and failures are cached.

Enabled only for checked conversion, where the result is a deterministic
function of the fixed environment and no universe constraints are
accumulated to replay; inference-mode conversion (which backtracks and
discards constraints) never consults the cache. On by default;
ROCQ_CONV_CACHE=0 disables it, ROCQ_CONV_CACHE_MAX bounds the table.

Cuts the heaviest checked conversion we measured by ~4x.
The cache from the previous commit used a Hashtbl of boxed entries. On a
heavy check that inserts ~60M entries within a single session, the entries
themselves become the dominant cost: not the hashing, but the major GC
tracing every one of those live boxed tuples and list cells.

Everything in an entry is a small integer once lift values are interned:
the cell-id pair packs into one machine int, and the interned lift ids,
problem kind and result pack into a second. Store them in two int arrays
with open addressing (linear probing, integer mix hash, doubling growth).
No per-entry allocation and nothing for the GC to trace.

Behaviour is unchanged (identical probe/hit/insert counts on the
benchmark, digit for digit). On the heaviest check this is a further ~2.6x
in time and drops peak memory by about a third.
@coqbot-app coqbot-app Bot added the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Jul 28, 2026
@herbelin

Copy link
Copy Markdown
Member

@coqbot bench

@coqbot-app

coqbot-app Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

🏁 Bench results:

┌─────────────────────────────────────┬──────────────────────────┬────────────────────────────────────────┬──────────────────────────┐
│                                     │      user time [s]       │            CPU instructions            │  max resident mem [KB]   │
│                                     │                          │                                        │                          │
│            package_name             │   NEW      OLD    PDIFF  │      NEW             OLD        PDIFF  │   NEW      OLD    PDIFF  │
├─────────────────────────────────────┼──────────────────────────┼────────────────────────────────────────┼──────────────────────────┤
│                        coq-bedrock2 │  270.53   363.33  -25.54 │  1998832398797   2898022147650  -31.03 │  864028   864984   -0.11 │
│                         coq-unimath │ 1837.17  1987.65   -7.57 │ 14276779795220  15809788111230   -9.70 │ 4010076  1861884  115.38 │
│                             coq-vst │  802.06   833.11   -3.73 │  5479101793479   5981225964271   -8.40 │ 4043484  2015484  100.62 │
│        coq-fiat-crypto-with-bedrock │ 7146.56  7344.60   -2.70 │ 56430490359440  58350718404688   -3.29 │ 2871684  2825192    1.65 │
│                    coq-fiat-parsers │  280.62   285.17   -1.60 │  2017492152378   2065319604155   -2.32 │ 2032076  2048776   -0.82 │
│  rocq-mathcomp-group-representation │   99.52   100.67   -1.14 │   656289432224    662513770768   -0.94 │ 1549056  1543028    0.39 │
│                           rocq-core │    7.38     7.46   -1.07 │    40663211373     40578225365    0.21 │  493896   494016   -0.02 │
│             rocq-mathcomp-ssreflect │    1.20     1.21   -0.83 │     7361883429      7354868117    0.10 │  596788   596804   -0.00 │
│              coq-mathcomp-odd-order │  626.80   630.24   -0.55 │  4195413820975   4195628770732   -0.01 │ 2608992  2603800    0.20 │
│                   coq-iris-examples │  382.73   384.67   -0.50 │  2365303802955   2365225172754    0.00 │ 1088892  1068788    1.88 │
│               coq-mathcomp-analysis │ 1369.41  1375.54   -0.45 │  9545923551404   9617395860922   -0.74 │ 2163984  2165332   -0.06 │
│                 rocq-mathcomp-field │  210.84   211.77   -0.44 │  1411572810179   1427192298809   -1.09 │ 2284840  2282680    0.09 │
│                    coq-math-classes │   86.52    86.89   -0.43 │   486870358640    490507990063   -0.74 │  545244   544508    0.14 │
│                            coq-corn │  663.23   666.01   -0.42 │  4246544244159   4264329440785   -0.42 │  646980   647936   -0.15 │
│          rocq-metarocq-translations │   17.14    17.21   -0.41 │   112861215953    113166360857   -0.27 │  890552   915912   -2.77 │
│                       coq-fiat-core │   59.93    60.17   -0.40 │   339508208716    338909012990    0.18 │  478580   478292    0.06 │
│                        rocq-runtime │   76.01    76.18   -0.22 │   554974331323    554755101712    0.04 │  542468   542088    0.07 │
│              rocq-mathcomp-solvable │  101.80   102.00   -0.20 │   651060218902    650711501096    0.05 │ 1076464  1069120    0.69 │
│              rocq-metarocq-template │   83.82    83.97   -0.18 │   555178022587    554555748156    0.11 │ 1158024  1151648    0.55 │
│                        rocq-bignums │   26.22    26.26   -0.15 │   156970162049    157949771983   -0.62 │  456928   457068   -0.03 │
│                           coq-color │  241.00   241.36   -0.15 │  1424894748299   1420497214730    0.31 │ 1158208  1166856   -0.74 │
│                         coq-coqutil │   49.61    49.68   -0.14 │   288168948496    287875018814    0.10 │  561308   561028    0.05 │
│                            coq-hott │  169.65   169.85   -0.12 │  1043650733768   1049534397624   -0.56 │  466716   467740   -0.22 │
│                 coq-category-theory │ 1141.81  1143.13   -0.12 │  8088807166087   8071437379628    0.22 │ 6741588  6385808    5.57 │
│                         rocq-stdlib │  252.45   252.60   -0.06 │  1469579335283   1466127136514    0.24 │  757164   759216   -0.27 │
│               rocq-metarocq-erasure │  451.59   451.83   -0.05 │  2939147568257   2932478876168    0.23 │ 1830048  1803728    1.46 │
│                 rocq-metarocq-pcuic │  622.30   622.54   -0.04 │  3814487710780   3804616033750    0.26 │ 2424032  2407640    0.68 │
│                rocq-metarocq-common │   42.78    42.79   -0.02 │   263060552408    262882772594    0.07 │  927956   948468   -2.16 │
│           rocq-metarocq-safechecker │  315.91   315.95   -0.01 │  2285374565642   2280265665905    0.22 │ 1750416  1746912    0.20 │
│                      rocq-equations │    8.38     8.38    0.00 │    54974535589     54935547475    0.07 │  421496   421752   -0.06 │
│                        coq-coqprime │   57.68    57.65    0.05 │   377654345146    377613733510    0.01 │  825040   826636   -0.19 │
│                  rocq-mathcomp-boot │   40.89    40.86    0.07 │   230947676310    230093427656    0.37 │  665996   661768    0.64 │
│          coq-performance-tests-lite │  892.47   891.73    0.08 │  6919705067637   6916438005237    0.05 │ 1521080  1540144   -1.24 │
│                        coq-rewriter │  337.65   337.24    0.12 │  2419469267780   2410426434190    0.38 │ 1480816  1431748    3.43 │
│                       coq-fourcolor │ 1378.54  1376.77    0.13 │ 12371488652895  12374335096380   -0.02 │  999132   999032    0.01 │
│                        coq-compcert │  315.57   315.16    0.13 │  1963473858761   1955954130909    0.38 │ 1171108  1221276   -4.11 │
│                 rocq-mathcomp-order │   90.47    90.32    0.17 │   615575201925    618391476430   -0.46 │  919396   918248    0.13 │
│ coq-neural-net-interp-computed-lite │  239.06   238.48    0.24 │  2244553510491   2243879092752    0.03 │  884048   874080    1.14 │
│                 rocq-metarocq-utils │   25.56    25.49    0.27 │   153992169419    153642462844    0.23 │  621604   626056   -0.71 │
│         coq-rewriter-perf-SuperFast │  475.29   473.56    0.37 │  3509994719276   3502316244301    0.22 │ 1253236  1272324   -1.50 │
│                      coq-coquelicot │   40.68    40.53    0.37 │   231690110401    230886794763    0.35 │  892236   881552    1.21 │
│          rocq-mathcomp-finite-group │   27.67    27.56    0.40 │   172032202047    170108698792    1.13 │  594948   568028    4.74 │
│               rocq-mathcomp-algebra │  391.68   390.04    0.42 │  2653758645654   2654173706213   -0.02 │ 1543432  1542500    0.06 │
│               coq-engine-bench-lite │  130.34   129.79    0.42 │   949450406246    944273113144    0.55 │ 1136232  1133156    0.27 │
│                           rocq-elpi │   17.78    17.66    0.68 │   117839961766    117836285419    0.00 │  486648   486604    0.01 │
│                            coq-core │    2.78     2.75    1.09 │    19301646778     19302453587   -0.00 │  113856   113604    0.22 │
└─────────────────────────────────────┴──────────────────────────┴────────────────────────────────────────┴──────────────────────────┘

🐢 Top 25 slow downs
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                            TOP 25 SLOW DOWNS                                                             │
│                                                                                                                                          │
│  OLD     NEW     DIFF    %DIFF     Ln                     FILE                                                                           │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 16.307  24.527  8.2200    50.41%  1515  coq-vst/floyd/VSU.v.html                                                                         │
│ 16.212  24.077  7.8650    48.51%  1209  coq-vst/floyd/Component.v.html                                                                   │
│ 16.355  23.672  7.3170    44.74%  1223  coq-vst/floyd/Component.v.html                                                                   │
│   6.09    11.5  5.4054    88.69%   196  coq-unimath/UniMath/CategoryTheory/Hyperdoctrines/HValuedSets.v.html                             │
│  8.153   12.47  4.3170    52.95%   783  coq-vst/floyd/Component.v.html                                                                   │
│  8.109  12.083  3.9740    49.01%  1509  coq-vst/floyd/Component.v.html                                                                   │
│   2.82    5.26  2.4388    86.39%   160  coq-unimath/UniMath/CategoryTheory/Hyperdoctrines/HValuedSets.v.html                             │
│   5.59    6.97  1.3765    24.62%   217  coq-fiat-crypto-with-bedrock/src/Bedrock/Field/Synthesis/Examples/p224_64_new.v.html             │
│   7.41    8.61  1.2012    16.22%   571  coq-fiat-crypto-with-bedrock/src/Bedrock/P256/Jacobian.v.html                                    │
│   41.6    42.5  0.9163     2.20%   246  coq-category-theory/Construction/DecoratedCospan/Category.v.html                                 │
│   11.0    11.8  0.8352     7.59%  2300  coq-fiat-crypto-with-bedrock/rupicola/bedrock2/compiler/src/compiler/FlatToRiscvFunctions.v.html │
│   50.6    51.4  0.7736     1.53%    27  coq-fiat-crypto-with-bedrock/src/Rewriter/Passes/ToFancyWithCasts.v.html                         │
│   12.6    13.3  0.7264     5.76%    97  coq-unimath/UniMath/CategoryTheory/Hyperdoctrines/HValuedSets.v.html                             │
│    202     203  0.7023     0.35%     8  coq-neural-net-interp-computed-lite/theories/MaxOfTwoNumbersSimpler/Computed/AllLogits.v.html    │
│   61.6    62.2  0.6280     1.02%   857  coq-mathcomp-analysis/theories/lebesgue_integral_theory/lebesgue_integral_differentiation.v.html │
│  1.006   1.539  0.5330    52.98%  1346  coq-vst/floyd/Component.v.html                                                                   │
│  0.586    1.12  0.5292    90.26%   298  coq-unimath/UniMath/CategoryTheory/Hyperdoctrines/HValuedSets.v.html                             │
│   48.6    49.1  0.5285     1.09%   277  coq-fiat-crypto-with-bedrock/src/Bedrock/P256/Jacobian.v.html                                    │
│   47.4    47.9  0.4853     1.02%     3  coq-fiat-crypto-with-bedrock/src/ExtractionJsOfOCaml/WithBedrock/fiat_crypto.v.html              │
│    105     105  0.4575     0.44%    22  coq-fiat-crypto-with-bedrock/src/Rewriter/Passes/ArithWithCasts.v.html                           │
│   2.38    2.83  0.4485    18.82%     8  coq-engine-bench-lite/coq/PerformanceDemos/repeated_conj.v.html                                  │
│  2.071   2.511  0.4400    21.25%   243  coq-vst/floyd/subsume_funspec.v.html                                                             │
│   2.66    3.08  0.4273    16.09%   335  coq-fiat-crypto-with-bedrock/src/Curves/Montgomery/XZProofs.v.html                               │
│ 0.0130   0.438  0.4252  3267.04%   159  coq-mathcomp-analysis/theories/hoelder.v.html                                                    │
│ 0.0247   0.438  0.4133  1673.28%   130  coq-mathcomp-analysis/theories/lebesgue_integral_theory/measurable_fun_approximation.v.html      │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
🐇 Top 25 speed ups
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                              TOP 25 SPEED UPS                                                              │
│                                                                                                                                            │
│  OLD     NEW      DIFF     %DIFF    Ln                     FILE                                                                            │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│   64.2    2.05  -62.1404  -96.80%   608  coq-fiat-crypto-with-bedrock/rupicola/bedrock2/bedrock2/src/bedrock2Examples/lightbulb.v.html     │
│   64.1    2.06  -62.0551  -96.78%   608  coq-bedrock2/bedrock2/src/bedrock2Examples/lightbulb.v.html                                       │
│   50.6  0.0434  -50.5919  -99.91%   376  coq-unimath/UniMath/ModelCategories/Generated/LNWFSMonoidalStructure.v.html                       │
│   45.1    10.1  -34.9765  -77.52%   578  coq-fiat-crypto-with-bedrock/rupicola/bedrock2/compiler/src/compiler/MMIO.v.html                  │
│ 29.673   0.057  -29.6160  -99.81%   147  coq-vst/veric/expr_lemmas4.v.html                                                                 │
│   40.2    10.9  -29.2451  -72.76%  1423  coq-fiat-crypto-with-bedrock/rupicola/bedrock2/compiler/src/compiler/FlatToRiscvFunctions.v.html  │
│ 29.229   0.025  -29.2040  -99.91%   194  coq-vst/veric/expr_lemmas4.v.html                                                                 │
│   25.4   0.252  -25.1035  -99.01%   550  coq-bedrock2/bedrock2/src/bedrock2Examples/insertionsort.v.html                                   │
│   25.2   0.251  -24.9754  -99.01%   550  coq-fiat-crypto-with-bedrock/rupicola/bedrock2/bedrock2/src/bedrock2Examples/insertionsort.v.html │
│   21.7   0.186  -21.5483  -99.14%   338  coq-unimath/UniMath/ModelCategories/Generated/LNWFSMonoidalStructure.v.html                       │
│   20.3    2.99  -17.3171  -85.27%   543  coq-unimath/UniMath/CategoryTheory/Presheaves/SigmaTypes.v.html                                   │
│   17.5   0.227  -17.2723  -98.70%   905  coq-unimath/UniMath/ModelCategories/Generated/LNWFSCocomplete.v.html                              │
│   12.0   0.830  -11.1452  -93.07%   216  coq-fiat-crypto-with-bedrock/src/Fancy/Barrett256.v.html                                          │
│   16.0    6.36   -9.6449  -60.25%   898  coq-fiat-crypto-with-bedrock/src/Bedrock/Secp256k1/JoyeLadder.v.html                              │
│   8.78   0.283   -8.4946  -96.77%   453  coq-unimath/UniMath/SyntheticHomotopyTheory/Circle2.v.html                                        │
│   11.7    6.58   -5.0983  -43.64%   118  coq-fiat-parsers/src/Parsers/Refinement/SharpenedJSON.v.html                                      │
│  5.029   0.102   -4.9270  -97.97%   407  coq-vst/floyd/for_lemmas.v.html                                                                   │
│   3.39   0.121   -3.2699  -96.43%   233  coq-fiat-crypto-with-bedrock/src/Bedrock/P256/RecodeProofs.v.html                                 │
│   5.30    3.14   -2.1620  -40.78%   210  coq-fiat-crypto-with-bedrock/src/Demo.v.html                                                      │
│   2.17  0.0542   -2.1167  -97.50%   243  coq-unimath/UniMath/ModelCategories/Examples.v.html                                               │
│   2.16  0.0528   -2.1118  -97.56%   459  coq-unimath/UniMath/ModelCategories/Examples.v.html                                               │
│   2.13   0.132   -2.0013  -93.83%   323  coq-fiat-crypto-with-bedrock/src/Bedrock/P256/RecodeProofs.v.html                                 │
│   2.05  0.0937   -1.9609  -95.44%   348  coq-unimath/UniMath/CategoryTheory/Presheaf.v.html                                                │
│   2.19   0.573   -1.6157  -73.84%   515  coq-unimath/UniMath/CategoryTheory/Presheaves/PiTypesStable.v.html                                │
│    235     234   -1.4839   -0.63%   141  coq-fiat-crypto-with-bedrock/src/UnsaturatedSolinasHeuristics/Tests.v.html                        │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants