package main import ( "fmt" "os" "runtime" "strconv" "sync" "time" ) var markGroup sync.WaitGroup func markMultiples(sieve []uint64, i int64, n0, n1 int64) { for j := n0; j < n1; j += 2 * i { sieve[j>>7] |= 1 << ((j & 0x7F) >> 1) } markGroup.Done() } func main() { n, err := strconv.ParseInt(os.Args[1], 10, 64) if err != nil { panic(err) } nCpus := int64(runtime.NumCPU()) t0 := time.Now() sieve := make([]uint64, (n>>7)+1) var found int64 var i int64 i = 2 found++ for i = 3; i < n; i += 2 { if (sieve[i>>7] & (1 << ((i & 0x7F) >> 1))) == 0 { found++ p := nCpus var jnext int64 // XXX - i * i can overflow. // bail out before that happens if n / i < i { continue; } for j := i * i; j < n; j = jnext { jnext = ((n-j)/(2*i)/p+1)*(2*i) + j if jnext > n { jnext = n } markGroup.Add(1) go markMultiples(sieve, i, j, jnext) p-- } markGroup.Wait() } } d := time.Since(t0) fmt.Println() fmt.Println(found, "primes found in", d) }