perf(callgrind): inline CLG_(get_fn_entry) to remove a per-basic-block call#28
Conversation
Greptile SummaryThe PR inlines the active-function array accessor to remove a hot-path cross-translation-unit call.
Confidence Score: 5/5The PR appears safe to merge. No blocking failures remain within the scope of this follow-up review.
|
| Filename | Overview |
|---|---|
| callgrind/fn.c | Exports the active-function array and removes the former out-of-line accessor. |
| callgrind/global.h | Declares the active-function array and defines the bounds-checked inline accessor. |
Reviews (5): Last reviewed commit: "perf(callgrind): inline CLG_(get_fn_entr..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
|
codspeed do you see a way to make the benches more stable? can we increase the number of iterations without having the workflow being too long? |
Yes — the instability comes from how many rounds each benchmark gets, and there's a clean way to increase iterations without letting the workflow run away. Why they were unstable: these are What I changed (in
On "without making the workflow too long": the The three knobs are exposed as CLI flags ( I validated that the generated config is accepted by the runner's parser. I couldn't produce a real walltime measurement in the sandbox ( Summary
Learnings updated. See what CodSpeed remembers about this repository. Was this response helpful? React with 👍 or 👎 to help us improve CodSpeedBot. |
|
I cherrypicked your commit on the base branch. Merge it in this pr so I can compare |
Done — I merged Since you cherry-picked the walltime-stabilization commit (
isolating the pure call-overhead removal. Merge details:
Merge commit: Summary
Was this response helpful? React with 👍 or 👎 to help us improve CodSpeedBot. |
168ac7c to
66eefbc
Compare
Unable to generate the flame graphsThe performance report has correctly been generated, but there was an internal error while generating the flame graphs for this run. We're working on fixing the issue. Feel free to contact us on Discord or at support@codspeed.io if the issue persists. |
…k call CLG_(setup_bbcc) runs on every basic-block execution and called the out-of-line CLG_(get_fn_entry) in fn.c once per BB (the separate_recursions > 1 path, active by default). Because the accessor lived in a different translation unit, the compiler could not inline what is a single array index. Expose current_fn_active as CLG_(current_fn_active) and move get_fn_entry into global.h as a static __inline__ accessor after CLG_ASSERT. Disassembly of the built tool confirms zero remaining call sites; Callgrind output is byte-for-byte identical (default and --separate-recs=3).
66eefbc to
3f8d868
Compare
Summary
Callgrind's
CLG_(setup_bbcc)runs on every basic-block execution and is one of the hottest functions in the profile. On each call it invokedCLG_(get_fn_entry)— an out-of-line function infn.c— to read the active-recursion level of the current function (theseparate_recursions > 1path, active by default since--separate-recsdefaults to2).Because
get_fn_entrylived in a different translation unit, the compiler could not inline what is a trivial one-line array index, leaving a realcall vgCallgrind_get_fn_entryexecuted once per basic block.Change
current_fn_activeasCLG_(current_fn_active)(declaredexterninglobal.h, defined infn.c).CLG_(get_fn_entry)intoglobal.has astatic __inline__accessor, placed after theCLG_ASSERTmacro so the bounds check is preserved unchanged.Verification (local, this build)
objdump -dof the builtcallgrind-amd64-linuxshows zerocall get_fn_entryinstructions, and the symbol is gone entirely fromnm— the accessor is inlined at every call site (setup_bbcc,get_cxt,push_cxt, …).summary:instruction counts are identical between baseline and optimized builds, and the fullcallgrind.outis byte-for-byte identical when the two builds are run back-to-back (isolating process-startup randomization). Verified both with default options and with--separate-recs=3. This is a pure call-overhead removal, not a semantic change.Performance
Measured with CodSpeed walltime mode on the macro runners during the optimization investigation, the change was consistently positive across back-to-back paired baseline/head runs (roughly +0.6% to +1.6%), comfortably above the ~0.2% run-to-run noise floor, with no benchmark regressing on aggregate.
Note: walltime could not be re-measured in the implementation sandbox (no
perfavailable, and the sandbox is x86_64 while the benchmark fixtures/runners are ARM64). The authoritative walltime impact is produced by this PR's CodSpeed CI run on thecodspeed-macrorunners.