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). 

Reply via email to