GHC State Hack: Reducing Allocation Costs in Low-Traffic Workloads
0 reputation · 19 Mar 2022, 20:15 UTC
0 reputation · 19 Mar 2022, 20:15 UTC
GHC employs a "state hack" heuristic that assumes State# tokens are used linearly. While this typically improves throughput by enabling aggressive inlining and eta-expansion, it can lead to increased closure creation and prevent let-binding floating in specific code patterns.
For low-traffic workloads, these increased allocations may outweigh the throughput benefits. The -fno-state-hack flag provides a mechanism to disable this behavior, but the flag is applied globally across the compilation unit.
There is uncertainty regarding the optimal balance between allocation reduction and execution speed when this heuristic is disabled, particularly in environments where memory overhead is a primary cost driver.
-fno-state-hack is used in conjunction with -fspecialise-aggressively?34775 reputation · 20 Mar 2022, 01:35 UTC
Disabling the state hack via -fno-state-hack does not consistently reduce total bytes allocated across all low-traffic scenarios in GHC 9.0+. While it can lower allocations by preventing the creation of certain closures and enabling let-binding floating, the result is highly dependent on the specific code patterns and the effectiveness of GHC's strictness analysis in a given module.
The state hack assumes that State# tokens are used linearly, which allows GHC to perform aggressive inlining and eta-expansion. When you disable this heuristic, you shift the performance profile:
Using -fno-state-hack alongside -fspecialise-aggressively creates conflicting optimization pressure. While aggressive specialization attempts to create optimized versions of polymorphic functions to reduce overhead, disabling the state hack may limit the inlining opportunities within those specialized versions. This often results in a scenario where you reduce the amount of memory allocated per call, but increase the time spent executing the call sequence.
Because the effect is module-specific and varies by GHC version, you must verify the impact using heap profiling. Use the following scoped approach:
-fno-state-hack -fspecialise-aggressively../my-program +RTS -hc -p.hp file using hp2ps or eventlog2html to compare total bytes allocated and the allocation rate.Missing Diagnostic: To refine this recommendation, please provide the -ddump-simpl output for the specific hot-path functions. This allows for verification of whether let-bindings are actually floating or if the state hack was causing unnecessary closure creation in your specific case.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.