Repository navigation
Open
Description
Part of #237.
Why
The FFT homogenization host evaluates one material point per voxel per iteration, millions of times per load step. The engine has gained iteration groups, systems, derivative plans and checkpoints since #173, and nobody has measured it since. The review found per-call allocations:
fold()(Property engine: residual systems set up at run time (#218) #229) allocates J, B and dx/dp per plan and system on everydifferentiate();derivative<R>()built its error text on every call (fixed in Partial derivatives: per-callback declarations and forward accumulation (#217) #227);checkpoint()(History checkpoints within a step and cutbacks in the report loop #225) serialises every history property throughstd::ostringstreamat every step start whenmax_cutbacks > 0.
There is no benchmark in the repo (tests/, examples/ and tools/ have none).
Design
benchmarks/engine_bench.cpp, a plainstd::chronoharness with no new dependency, built whenNUMSIM_MATERIALS_BUILD_BENCHMARKS=ONand always at-O3 -DNDEBUG. It runs these cases, each per point update after warm-up, as median of N runs:- linear elasticity:
update(); - the same with
derivative(stress, strain); - J2 on
systemwith the implicit-function-theorem tangent; - the damage chain with accumulated derivative;
- the nonlinear mean-field composite (iteration group);
checkpoint()+restore().
- linear elasticity:
- Allocation counter. A replaced global
operator newin the benchmark executable counts allocations. Each case asserts zero allocations per update after the first call, and a test target runs the same assertion as a gtest, so CI catches a regression. - Fixes:
- J, B and dx/dp become members of the derivative plan, sized once;
- Eigen solves into preallocated storage (
PartialPivLUmember,compute+solveinto a member); checkpoint()writes into a reusablestd::vector<std::byte>buffer through the existingserialize()hooks, or a binary path ifserializeneeds a stream;- anything else the counter finds.
- Baseline. Run the same cases on main, before Epic: property engine 2 — inspectable graph, in-engine iteration, residual systems and derivative edges #221, where the API exists (cases 1, 2 via the hand-written tangent, and 4). Report the table in the PR.
Tests
- A gtest
EngineHotPath.UpdateAndDifferentiateDoNotAllocatewith the countingoperator new, for the cases above (red first on the current code). - The benchmark builds in CI. It only runs there, without timing assertions, because CI timing is noisy.
Depends on
#232 (the fixes land in the split units).
Out of scope
- SIMD or batching several points per call; that belongs to the FFT host design.
- Threading.
Metadata
Metadata
Assignees
Labels
No labels
Activity