Start goroutines once and use channels to distribute work
This commit is contained in:
parent
cfb18dec75
commit
5d3af658d7
|
@ -5,17 +5,24 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var markGroup sync.WaitGroup
|
type work struct {
|
||||||
|
i int64
|
||||||
|
n0, n1 int64
|
||||||
|
}
|
||||||
|
|
||||||
func markMultiples(sieve []uint64, i int64, n0, n1 int64) {
|
type result bool
|
||||||
for j := n0; j < n1; j += 2 * i {
|
|
||||||
sieve[j>>7] |= 1 << ((j & 0x7F) >> 1)
|
func markMultiples(sieve []uint64, workCh chan work, resultCh chan result) {
|
||||||
|
for {
|
||||||
|
w := <-workCh
|
||||||
|
for j := w.n0; j < w.n1; j += 2 * w.i {
|
||||||
|
sieve[j>>7] |= 1 << ((j & 0x7F) >> 1)
|
||||||
|
}
|
||||||
|
resultCh <- true
|
||||||
}
|
}
|
||||||
markGroup.Done()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -26,8 +33,13 @@ func main() {
|
||||||
nCpus := int64(runtime.NumCPU())
|
nCpus := int64(runtime.NumCPU())
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
sieve := make([]uint64, (n>>7)+1)
|
sieve := make([]uint64, (n>>7)+1)
|
||||||
var found int64
|
workCh := make(chan work)
|
||||||
|
resultCh := make(chan result)
|
||||||
var i int64
|
var i int64
|
||||||
|
for i = 0; i < nCpus; i++ {
|
||||||
|
go markMultiples(sieve, workCh, resultCh)
|
||||||
|
}
|
||||||
|
var found int64
|
||||||
i = 2
|
i = 2
|
||||||
found++
|
found++
|
||||||
for i = 3; i < n; i += 2 {
|
for i = 3; i < n; i += 2 {
|
||||||
|
@ -41,16 +53,19 @@ func main() {
|
||||||
if n / i < i {
|
if n / i < i {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
workers := 0
|
||||||
for j := i * i; j < n; j = jnext {
|
for j := i * i; j < n; j = jnext {
|
||||||
jnext = ((n-j)/(2*i)/p+1)*(2*i) + j
|
jnext = ((n-j)/(2*i)/p+1)*(2*i) + j
|
||||||
if jnext > n {
|
if jnext > n {
|
||||||
jnext = n
|
jnext = n
|
||||||
}
|
}
|
||||||
markGroup.Add(1)
|
workCh <-work{ i, j, jnext }
|
||||||
go markMultiples(sieve, i, j, jnext)
|
workers++
|
||||||
p--
|
p--
|
||||||
}
|
}
|
||||||
markGroup.Wait()
|
for k := 0; k < workers; k++ {
|
||||||
|
_ = <-resultCh
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d := time.Since(t0)
|
d := time.Since(t0)
|
||||||
|
|
Loading…
Reference in New Issue