code wiki / (root) / _primes_bitpacked_inline.nx

_primes_bitpacked_inline.nx source

↩ module page · 76 lines · 2264 B

1// _primes_bitpacked_inline.nx -- bit-packed sieve with MANUALLY inlined bit ops. 2// 3// Same algorithm as _primes_bitpacked.nx, but all bit-get / bit-set 4// calls are inlined into the hot loop -- substrate backend doesn't 5// aggressively inline so we do it by hand. 6 7import "syscalls.nx" 8 9const SIEVE_SIZE: i64 = 1000000 10const N_PASSES: i64 = 100 11 12func one_pass(buf: *u8, half: i64, byte_count: i64) -> i64 { 13 var i: i64 = 0 14 while i < byte_count { 15 buf[i] = 0 as u8 16 i = i + 1 17 } 18 var factor: i64 = 3 19 while factor * factor <= SIEVE_SIZE { 20 let factor_idx: i64 = (factor - 3) / 2 21 var fi: i64 = factor_idx 22 var done: i64 = 0 23 while done == 0 { 24 if fi >= half { done = 1 } 25 if done == 0 { 26 // INLINE bit_get 27 let byte_idx_g: i64 = fi >> 3 28 let bit_idx_g: i64 = fi & 7 29 let bit_g: i64 = ((buf[byte_idx_g] as i64) >> bit_idx_g) & 1 30 if bit_g == 0 { done = 1 } 31 if done == 0 { fi = fi + 1 } 32 } 33 } 34 if fi >= half { return -1 } 35 let cur_num: i64 = 2 * fi + 3 36 var mult: i64 = cur_num * cur_num 37 while mult <= SIEVE_SIZE { 38 let idx: i64 = (mult - 3) / 2 39 // INLINE bit_set 40 let byte_idx_s: i64 = idx >> 3 41 let bit_idx_s: i64 = idx & 7 42 let mask: i64 = 1 << bit_idx_s 43 buf[byte_idx_s] = ((buf[byte_idx_s] as i64) | mask) as u8 44 mult = mult + 2 * cur_num 45 } 46 factor = cur_num + 2 47 } 48 var count: i64 = 1 49 var k: i64 = 0 50 while k < half { 51 // INLINE bit_get 52 let bi: i64 = k >> 3 53 let bi_off: i64 = k & 7 54 let b: i64 = ((buf[bi] as i64) >> bi_off) & 1 55 if b == 0 { 56 let n: i64 = 2 * k + 3 57 if n <= SIEVE_SIZE { count = count + 1 } 58 } 59 k = k + 1 60 } 61 return count 62} 63 64func main() -> i64 { 65 let half: i64 = SIEVE_SIZE / 2 66 let byte_count: i64 = (half + 7) / 8 67 let buf: *u8 = sys_mmap(byte_count) 68 var p: i64 = 0 69 var c: i64 = 0 70 while p < N_PASSES { 71 c = one_pass(buf, half, byte_count) 72 p = p + 1 73 } 74 if c != 78498 { return 2 } 75 return 0 76}