So I'm compiling some new code in 0.18.0. This code code compiles and runs correctly as one process with no problems. proc segsieve(Kn: int) = # for Kn resgroups|bytes in segment ... for indx in 0..5: # for nextp row indexes, var r = indx + 1 # indx|r: 0 -> 1, 1 -> 2, 2 -> 3, 3 -> 4 if indx > 3: r += 1 # indx|r: 4 -> 6, 5 -> 7 restracks in seg let biti = uint8(1 shl r) # set its residue track bit mask let row = indx * pcnt # set address to its restrack in 'nextp' for j, prime in primes: # for each prime r1..sqrt(N) if nextp[row + j] < Kn.uint: # if 1st mult resgroup is within 'seg' var k = int(nextp[row + j]) # starting from this resgroup in 'seg' while k < Kn: # for each primenth byte to end of 'seg' seg[k] = seg[k] or biti # mark restrack bit in byte as nonprime k += prime # compute next prime multiple resgroup nextp[row + j] = uint(k-Kn) # save 1st resgroup in next eligible seg else: nextp[row+j] -= Kn.uint # do if 1st mult resgroup not within seg ...
Then I separate it into 2 processes, to make it parallel ready, but first run it single threaded. proc residue_sieve(Kn, r, indx: int) = let biti = uint8(1 shl r) # set its residue track bit mask let row = indx * pcnt # set address to its restrack in 'nextp' for j, prime in primes: # for each prime r1..sqrt(N) if nextp[row + j] < Kn.uint: # if 1st mult resgroup is within 'seg' var k = int(nextp[row + j]) # starting from this resgroup in 'seg' while k < Kn: # for each primenth byte to end of 'seg' seg[k] = seg[k] or biti # mark restrack bit in byte as nonprime k += prime # compute next prime multiple resgroup nextp[row + j] = uint(k-Kn) # save 1st resgroup in next eligible seg else: nextp[row+j] -= Kn.uint # do if 1st mult resgroup not within seg proc segsieve(Kn: int) = # for Kn resgroups|bytes in segment ... for indx in 0..5: # for nextp row indexes, var r = indx + 1 # indx|r: 0 -> 1, 1 -> 2, 2 -> 3, 3 -> 4 if indx > 3: r += 1 # indx|r: 4 -> 6, 5 -> 7 restracks in seg residue_sieve(Kn,r,indx) # sieve on just the necessary restracks ... It compiles with no problems, and runs correctly, until the input values gets past a certain size, then it throws a runtime SEGFAULT error. SIGSEGV: Illegal storage access. (Attempt to read from nil?) This seems like a clear compiler error. Doing the same algorithm|work in one process compiles|runs correctly, while breaking it into 2 processes compiles, but only works correctly for input values below some ERROR value. It seems the error occurs reading from **nextp[]** or **seg[]** 's mem. I have no idea why it's doing that, or how to fix it. Also, the single process compiled binary (111128) is about 18K bytes smaller than for the separated processes (129991).