code wiki / (root) / nx_gpu_timestamp_lib.nx

nx_gpu_timestamp_lib.nx source

↩ module page · 37 lines · 1595 B

1// Lossless WebGPU timestamp transport: canonical decimal uint64, two unsigned 32-bit limbs. 2// Values are raw device-clock nanoseconds, never host-clock timestamps or GPU submission time. 3const GTS_LIMB_BASE: i64 = 4294967296 4const GTS_LIMB_MAX: i64 = GTS_LIMB_BASE-1 5const GTS_DECIMAL_MAX: i64 = 20 6// Caller supplies two words. Invalid input leaves them unchanged. 7func gts_u64(b: *u8, n: i64, out: *i64) -> i64 { 8 if n<1 || n>GTS_DECIMAL_MAX { return 0 } 9 if n>1 { if b[0]==48 as u8 { return 0 } } 10 var lo: i64=0; var hi: i64=0; var i: i64=0 11 while i<n { 12 let c: i64=b[i] as i64 13 if c<48 || c>57 { return 0 } 14 let next: i64=lo*10+c-48 15 hi=hi*10+next/GTS_LIMB_BASE 16 lo=next%GTS_LIMB_BASE 17 if hi>GTS_LIMB_MAX { return 0 } 18 i=i+1 19 } 20 out[0]=lo; out[1]=hi; return 1 21} 22// Caller owns six scratch words. All three decimal inputs must be canonical uint64. 23// Reversed intervals are refused; no assumption about timestamp counter wrapping is made. 24func gts_interval(start: *u8, sn: i64, finish: *u8, fn: i64, duration: *u8, dn: i64, scratch: *i64) -> i64 { 25 let endpair: *i64=((scratch as i64)+16) as *i64 26 let diffpair: *i64=((scratch as i64)+32) as *i64 27 if gts_u64(start,sn,scratch)==0 { return 0 } 28 if gts_u64(finish,fn,endpair)==0 { return 0 } 29 if gts_u64(duration,dn,diffpair)==0 { return 0 } 30 if endpair[1]<scratch[1] { return 0 } 31 if endpair[1]==scratch[1] { if endpair[0]<scratch[0] { return 0 } } 32 var dlo: i64=endpair[0]-scratch[0] 33 var dhi: i64=endpair[1]-scratch[1] 34 if dlo<0 { dlo=dlo+GTS_LIMB_BASE; dhi=dhi-1 } 35 if dlo!=diffpair[0] || dhi!=diffpair[1] { return 0 } 36 return 1 37}