code wiki / _hdl_build / nx_compile_perf.nx

nx_compile_perf.nx source

↩ module page · 57 lines · 2784 B

1// nx_compile_perf.nx -- the Engineer's COMPILE-TROUBLESHOOTING capability (operator: "if compile is slow 2// research how teams address this to troubleshoot quickly"). Grounded in the established practice 3// (ccache, incremental builds, parallel -j, clang -ftime-trace / gcc -ftime-report profiling, bisection): 4// - the Engineer picks the right LEVER by symptom: a HANG -> bisect-to-function + split (nx_hang_resolve); 5// SLOW-but-completes -> CACHE (skip unchanged modules by source-hash, the #1 win since the team 6// recompiles whole files), + INCREMENTAL (only changed), + PARALLEL (-j), + PROFILE (find the hot fn). 7// - all under the operator's SLA: troubleshoot in <=3 steps; a CACHE HIT is the 1-step optimal (~instant). 8// license_tier: ORIGINAL Pairs with nx_hang_resolve + nx_build_safe. 9// Refs: ccache; clang -ftime-trace (aras-p.info); gcc -ftime-report/-H; Clang Build Analyzer. 10 11import "nx_syscalls.nx" 12 13const CP_LEVER_CACHE: i64 = 1 14const CP_LEVER_INCREMENTAL: i64 = 2 15const CP_LEVER_PARALLEL: i64 = 3 16const CP_LEVER_PROFILE: i64 = 4 17const CP_LEVER_BISECT_SPLIT:i64 = 5 18 19const CP_SYMPTOM_HANG: i64 = 1 20const CP_SYMPTOM_SLOW: i64 = 2 21 22// pick the right lever for the symptom. 23func cp_lever_for(symptom: i64) -> i64 { 24 if symptom == CP_SYMPTOM_HANG { return CP_LEVER_BISECT_SPLIT } 25 return CP_LEVER_CACHE 26} 27 28// CACHE: a module whose source-hash matches its cached hash is UNCHANGED -> skip compile entirely. 29func cp_cache_hit(source_hash: i64, cached_hash: i64) -> i64 { if source_hash == cached_hash { return 1 } return 0 } 30 31// the dominant speedup: fraction of modules that are unchanged (cache-hit) -> skipped compiles. 32func cp_cache_speedup_permil(total_modules: i64, unchanged_modules: i64) -> i64 { 33 if total_modules <= 0 { return 0 } 34 return (unchanged_modules * 1000) / total_modules 35} 36 37// parallel build time (approx): serial_time / min(modules, cores). 38func cp_parallel_time(serial_time: i64, modules: i64, cores: i64) -> i64 { 39 var w: i64 = modules; if cores < w { w = cores } 40 if w <= 0 { return serial_time } 41 return serial_time / w 42} 43 44// PROFILE: which function/module dominates compile time? (the hot spot to attack -- -ftime-trace style) 45func cp_hottest(times: *i64, n: i64) -> i64 { 46 var best: i64 = 0 - 1; var bt: i64 = 0 - 1; var i: i64 = 0 47 while i < n { if times[i] > bt { bt = times[i]; best = i } i = i + 1 } 48 return best 49} 50 51// troubleshoot steps: cache-hit -> 0 (skipped, instant); known hang -> 1 (split); unknown slow -> 3 (profile+isolate+fix). 52func cp_troubleshoot_steps(symptom: i64, cache_hit: i64) -> i64 { 53 if cache_hit == 1 { return 0 } 54 if symptom == CP_SYMPTOM_HANG { return 1 } 55 return 3 56} 57func cp_within_sla(steps: i64) -> i64 { if steps <= 3 { return 1 } return 0 }