code wiki / (root) / nx_etg_probe_cpu.nx

nx_etg_probe_cpu.nx source

↩ module page · 336 lines · 11120 B

1// nx_etg_probe_cpu.nx -- E3 first real CPU-tier ETG probe. 2// 3// Bridges the pre-existing nx_calibrate.nx CPU measurements (SA-2 4// shipped) into the ETG framework (E1 NxEtgEntry attestation + E2 5// tournament selector). First REAL silicon probe in the substrate. 6// 7// Two surfaces: 8// 9// 1. nx_etg_classify_outcome(claim, measured, low_thresh_per_1000, 10// high_thresh_per_1000) -> i64 11// Universal classifier: given a vendor CLAIM value and an 12// empirical MEASURED value, classifies the outcome per the 13// 11-value NX_ETG_OUTCOME_* taxonomy. Used by every per-tier 14// probe (CPU / GPU / NVMe / network). Permilles (per-1000) 15// keep the math integer. 16// 17// 2. nx_etg_probe_cpu_syscall_roundtrip(claim_ns, low_thresh_per_1000, 18// high_thresh_per_1000, entry, 19// silicon_serial, selector_version, 20// timestamp_q14) -> i64 21// Runs nx_calibrate_run, extracts the syscall_ns_clock_gettime 22// measurement, classifies vs claim, emits an NxEtgEntry. Returns 23// the outcome (or negative on error). 24// 25// Composes: 26// [[NISHI_ETG_ROADMAP]] E3 (this is the first real probe) 27// nx_etg.nx (E1 NxEtgEntry attestation; SHIPPED) 28// nx_calibrate.nx (SA-2 CPU calibration; SHIPPED) -- the EMPIRICAL 29// MEASUREMENT layer this probe wraps in ETG semantics 30// [[NISHI_SELF_ASSEMBLY_ROADMAP]] SA-2 (prior art being lifted up) 31// [[feedback-physical-truth-over-published-docs-silicon-empirical-gamification]] 32// (cardinal: vendor claim is HYPOTHESIS, calibration measurement 33// is TRUTH; classifier records which side told the truth) 34// 35// Outcome classification rules: 36// measured == 0 || claim == 0 => INCONCLUSIVE (no comparison possible) 37// measured > claim * (1 + high/1000) => FALSIFIED (silicon worse than claimed) 38// measured < claim * (1 - low/1000) => VENDOR_LIED_OMISSION (better than claimed) 39// otherwise => CONFIRMED (within tolerance) 40// 41// Why permille thresholds: simple integer math; 100/1000 = 10% is a 42// reasonable default tolerance for syscall timings. 43 44// nx_safety_envelope: 45// intended_use: "first real CPU-tier ETG probe; bridges 46// nx_calibrate empirical measurements into 47// ETG NxEtgEntry attestations; demonstrates 48// end-to-end E1+E2+E3 wiring" 49// sil_target: SIL2 50// evidence: [kat_classifier_taxonomy_complete, 51// kat_classifier_boundaries_correct, 52// kat_real_calibration_emits_valid_entry] 53// hazard_register: [bug-tape-permille-overflow-on-large-claim, 54// bug-tape-divide-by-zero-claim, 55// bug-tape-measurement-noise-misclassified] 56// verdict: NOT_YET_EVALUATED 57 58import "nx_syscalls.nx" 59import "nx_calibrate.nx" 60import "nx_etg.nx" 61 62// ===== Outcome classifier ========================================= 63// 64// Permille thresholds (per-1000) keep math integer: 65// low_thresh_per_1000 = 100 => 10% lower tolerance 66// high_thresh_per_1000 = 100 => 10% upper tolerance 67// 68// Returns NX_ETG_OUTCOME_*. 69 70func nx_etg_classify_outcome( 71 claim: i64, 72 measured: i64, 73 low_thresh_per_1000: i64, 74 high_thresh_per_1000: i64 75) -> i64 { 76 if claim == 0 { return NX_ETG_OUTCOME_INCONCLUSIVE } 77 if measured == 0 { return NX_ETG_OUTCOME_INCONCLUSIVE } 78 79 // upper bound: claim * (1 + high/1000) = (claim * (1000 + high)) / 1000 80 let upper: i64 = (claim * (1000 + high_thresh_per_1000)) / 1000 81 if measured > upper { return NX_ETG_OUTCOME_FALSIFIED } 82 83 // lower bound: claim * (1 - low/1000) = (claim * (1000 - low)) / 1000 84 let lower: i64 = (claim * (1000 - low_thresh_per_1000)) / 1000 85 if measured < lower { return NX_ETG_OUTCOME_VENDOR_LIED_OMISSION } 86 87 return NX_ETG_OUTCOME_CONFIRMED 88} 89 90// ===== Real CPU syscall-roundtrip probe =========================== 91// 92// Runs nx_calibrate_run + classifies syscall_ns_clock_gettime vs 93// the vendor claim + emits an NxEtgEntry. Returns the outcome on 94// success, or a negative value on error. 95// 96// This is the FIRST REAL silicon-side ETG probe. The substrate 97// measures what THIS die actually does for a clock_gettime syscall, 98// then records the verdict against whatever the docs / driver claim. 99 100func nx_etg_probe_cpu_syscall_roundtrip( 101 claim_ns: i64, 102 low_thresh_per_1000: i64, 103 high_thresh_per_1000: i64, 104 entry: *NxEtgEntry, 105 silicon_serial: i64, 106 selector_version: i64, 107 timestamp_q14: i64 108) -> i64 { 109 let cal: *NxCalibrationRecord = nx_calibrate_new() 110 let rc: i64 = nx_calibrate_run(cal) 111 if rc != 0 { return -10 } 112 113 let measured: i64 = cal.syscall_ns_clock_gettime 114 let outcome: i64 = nx_etg_classify_outcome( 115 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000 116 ) 117 118 let rc_attest: i64 = nx_etg_entry_init( 119 entry, 120 silicon_serial, 121 NX_ETG_PROBE_CPU_SYSCALL, 122 NX_ETG_CLAIM_VENDOR_DOC, 123 claim_ns, 124 measured, 125 outcome, 126 selector_version, 127 timestamp_q14 128 ) 129 if rc_attest != 0 { return -20 } 130 131 return outcome 132} 133 134// ===== Real CPU int_alu dependent-chain probe ===================== 135// 136// Composes nx_calibrate's int_alu_ps_per_op measurement: a dependent- 137// chain ADD throughput in picoseconds per op. The vendor "claim" 138// for picosecond-per-op is rarely published; this probe primarily 139// records measurement for downstream conductor cost-model use, and 140// the classifier verifies it sits in a plausible band when a claim 141// is provided. 142// 143// probe_kind: NX_ETG_PROBE_CPU_ISA (closest taxonomy slot -- 144// dependent-chain ALU throughput characterizes the ISA's int-add unit). 145 146func nx_etg_probe_cpu_int_alu( 147 claim_ps_per_op: i64, 148 low_thresh_per_1000: i64, 149 high_thresh_per_1000: i64, 150 entry: *NxEtgEntry, 151 silicon_serial: i64, 152 selector_version: i64, 153 timestamp_q14: i64 154) -> i64 { 155 let cal: *NxCalibrationRecord = nx_calibrate_new() 156 let rc: i64 = nx_calibrate_run(cal) 157 if rc != 0 { return -10 } 158 159 let measured: i64 = cal.int_alu_ps_per_op 160 let outcome: i64 = nx_etg_classify_outcome( 161 claim_ps_per_op, measured, low_thresh_per_1000, high_thresh_per_1000 162 ) 163 164 let rc_attest: i64 = nx_etg_entry_init( 165 entry, 166 silicon_serial, 167 NX_ETG_PROBE_CPU_ISA, 168 NX_ETG_CLAIM_VENDOR_DOC, 169 claim_ps_per_op, 170 measured, 171 outcome, 172 selector_version, 173 timestamp_q14 174 ) 175 if rc_attest != 0 { return -20 } 176 177 return outcome 178} 179 180// ===== Real CPU mem-bandwidth probe =============================== 181// 182// Composes nx_calibrate's mem_bw_mib_per_s measurement: linear-copy 183// memory bandwidth in MiB/s. Critical for conductor scheduling: 184// vendor RAM datasheets routinely overstate sustainable bandwidth 185// because their numbers assume ideal DIMM topology + zero contention. 186// 187// probe_kind: NX_ETG_PROBE_STORAGE_RAM (RAM is a storage tier in the 188// per-tier catalog). 189 190func nx_etg_probe_cpu_mem_bw( 191 claim_mib_per_s: i64, 192 low_thresh_per_1000: i64, 193 high_thresh_per_1000: i64, 194 entry: *NxEtgEntry, 195 silicon_serial: i64, 196 selector_version: i64, 197 timestamp_q14: i64 198) -> i64 { 199 let cal: *NxCalibrationRecord = nx_calibrate_new() 200 let rc: i64 = nx_calibrate_run(cal) 201 if rc != 0 { return -10 } 202 203 let measured: i64 = cal.mem_bw_mib_per_s 204 let outcome: i64 = nx_etg_classify_outcome( 205 claim_mib_per_s, measured, low_thresh_per_1000, high_thresh_per_1000 206 ) 207 208 let rc_attest: i64 = nx_etg_entry_init( 209 entry, 210 silicon_serial, 211 NX_ETG_PROBE_STORAGE_RAM, 212 NX_ETG_CLAIM_VENDOR_DOC, 213 claim_mib_per_s, 214 measured, 215 outcome, 216 selector_version, 217 timestamp_q14 218 ) 219 if rc_attest != 0 { return -20 } 220 221 return outcome 222} 223 224// ===== Real CPU cache-hierarchy probes ============================ 225// 226// nx_calibrate already measures L1 / L2 / RAM access latency in ns 227// across 4 KiB / 256 KiB / 16 MiB working sets respectively. 228// Three probes wire each tier into the ETG framework. Vendor 229// datasheets typically publish "L1 hit latency ~4 cycles" but 230// per-die actual latency varies with: silicon binning, ambient 231// thermal, BIOS RAPL throttling, hyperthread contention, prefetcher 232// state, page-walk overhead, replacement-policy variant (LRU vs 233// RRIP vs DRRIP). ETG records the empirical truth per silicon 234// serial. 235 236func nx_etg_probe_cpu_cache_l1( 237 claim_ns: i64, 238 low_thresh_per_1000: i64, 239 high_thresh_per_1000: i64, 240 entry: *NxEtgEntry, 241 silicon_serial: i64, 242 selector_version: i64, 243 timestamp_q14: i64 244) -> i64 { 245 let cal: *NxCalibrationRecord = nx_calibrate_new() 246 let rc: i64 = nx_calibrate_run(cal) 247 if rc != 0 { return -10 } 248 249 let measured: i64 = cal.mem_ns_per_access_l1 250 let outcome: i64 = nx_etg_classify_outcome( 251 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000 252 ) 253 254 let rc_attest: i64 = nx_etg_entry_init( 255 entry, 256 silicon_serial, 257 NX_ETG_PROBE_CPU_CACHE, 258 NX_ETG_CLAIM_VENDOR_DOC, 259 claim_ns, 260 measured, 261 outcome, 262 selector_version, 263 timestamp_q14 264 ) 265 if rc_attest != 0 { return -20 } 266 267 return outcome 268} 269 270func nx_etg_probe_cpu_cache_l2( 271 claim_ns: i64, 272 low_thresh_per_1000: i64, 273 high_thresh_per_1000: i64, 274 entry: *NxEtgEntry, 275 silicon_serial: i64, 276 selector_version: i64, 277 timestamp_q14: i64 278) -> i64 { 279 let cal: *NxCalibrationRecord = nx_calibrate_new() 280 let rc: i64 = nx_calibrate_run(cal) 281 if rc != 0 { return -10 } 282 283 let measured: i64 = cal.mem_ns_per_access_l2 284 let outcome: i64 = nx_etg_classify_outcome( 285 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000 286 ) 287 288 let rc_attest: i64 = nx_etg_entry_init( 289 entry, 290 silicon_serial, 291 NX_ETG_PROBE_CPU_CACHE, 292 NX_ETG_CLAIM_VENDOR_DOC, 293 claim_ns, 294 measured, 295 outcome, 296 selector_version, 297 timestamp_q14 298 ) 299 if rc_attest != 0 { return -20 } 300 301 return outcome 302} 303 304func nx_etg_probe_cpu_cache_ram( 305 claim_ns: i64, 306 low_thresh_per_1000: i64, 307 high_thresh_per_1000: i64, 308 entry: *NxEtgEntry, 309 silicon_serial: i64, 310 selector_version: i64, 311 timestamp_q14: i64 312) -> i64 { 313 let cal: *NxCalibrationRecord = nx_calibrate_new() 314 let rc: i64 = nx_calibrate_run(cal) 315 if rc != 0 { return -10 } 316 317 let measured: i64 = cal.mem_ns_per_access_ram 318 let outcome: i64 = nx_etg_classify_outcome( 319 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000 320 ) 321 322 let rc_attest: i64 = nx_etg_entry_init( 323 entry, 324 silicon_serial, 325 NX_ETG_PROBE_STORAGE_RAM, 326 NX_ETG_CLAIM_VENDOR_DOC, 327 claim_ns, 328 measured, 329 outcome, 330 selector_version, 331 timestamp_q14 332 ) 333 if rc_attest != 0 { return -20 } 334 335 return outcome 336}