Commit 5faa3c3
Add an attribute inline-cache benchmark to cinderx/benchmarks
Summary:
`LOAD_ATTR` and `STORE_ATTR` cost almost entirely depends on the *layout* of
the receiver, where the attribute physically lives and what has to be checked
to prove a cached answer is still valid. There was no benchmark isolating
that, so `attr_cache.py` builds one receiver per distinct layout CPython 3.12,
3.14 and 3.15 can produce and hammers a separately generated hot function
against each, one cache shape per workload.
Storage layouts: `inline` (managed dict, values still inline), `split`
(materialized dict sharing the type's keys), `combined` (dict detached and
unshared), `exhausted` (shared keys full, name absent from them), `dictoffset`
(non-managed heap type with a positive `tp_dictoffset`), `slots`, `slotsdict`,
`varsize` (managed dict on a variable-sized type, which gets no inline values
on 3.14+ but does on 3.12) and `afteritems` (`__slots__` on a `tuple`
subclass, 3.15 only, skipped elsewhere). Lookup kinds that bypass instance
storage: `classvar`, `property`, `descriptor`, `getset`, `method`, `typeattr`,
`module`, `getattr`, `getattribute`. Polymorphic runs are separate workloads,
`poly2` through `poly16` plus `polylayout` and `polytype`, so the megamorphic
cliff past `CINDERX_JIT_ATTR_CACHE_SIZE` and the single-entry type-attribute
cache both show up on their own lines.
Receivers are passed in as an untyped `list`, which keeps the JIT from folding
loads into raw field accesses and holds the sites on the inline-cache path
being measured. Results are ns per attribute op, reported as the median of the
timed runs.
Three flags support verifying rather than just timing. `--describe` reports
the layout each workload's receivers actually ended up with, read through the
GC so the probe does not itself materialize a dict. `--specialization` reports
which adaptive-interpreter opcode CPython settled on. Every result block
prints whether the hot function was really JIT-compiled.
`--cinderx` and `--compare` follow `inference_pipeline.py`. Also adds a
`py_versions` argument to `cinderx_benchmark_binary` so this benchmark, whose
only dep is click, can also generate a 3.15 variant for the 3.15-only layouts.
`_cinderx` is not wired into `python_binary` for 3.15, so that variant
measures the interpreter only and warns on stderr.
Reviewed By: yoney
Differential Revision: D114683513
fbshipit-source-id: 8967cf54df165ddd660d7a73cdb46cf09ff787d41 parent 8803001 commit 5faa3c3
2 files changed
Lines changed: 994 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
33 | 65 | | |
34 | 66 | | |
35 | 67 | | |
| |||
130 | 162 | | |
131 | 163 | | |
132 | 164 | | |
| 165 | + | |
133 | 166 | | |
134 | 167 | | |
135 | 168 | | |
| |||
0 commit comments