From 5d3af658d70283dd7242f50d662d1a6f401fb0a7 Mon Sep 17 00:00:00 2001 From: "Peter J. Holzer" Date: Tue, 13 Jul 2021 12:09:17 +0200 Subject: [PATCH] Start goroutines once and use channels to distribute work --- eratosthenes_parallel.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/eratosthenes_parallel.go b/eratosthenes_parallel.go index 0489826..dad4644 100644 --- a/eratosthenes_parallel.go +++ b/eratosthenes_parallel.go @@ -5,17 +5,24 @@ import ( "os" "runtime" "strconv" - "sync" "time" ) -var markGroup sync.WaitGroup +type work struct { + i int64 + n0, n1 int64 +} -func markMultiples(sieve []uint64, i int64, n0, n1 int64) { - for j := n0; j < n1; j += 2 * i { - sieve[j>>7] |= 1 << ((j & 0x7F) >> 1) +type result bool + +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() { @@ -26,8 +33,13 @@ func main() { nCpus := int64(runtime.NumCPU()) t0 := time.Now() sieve := make([]uint64, (n>>7)+1) - var found int64 + workCh := make(chan work) + resultCh := make(chan result) var i int64 + for i = 0; i < nCpus; i++ { + go markMultiples(sieve, workCh, resultCh) + } + var found int64 i = 2 found++ for i = 3; i < n; i += 2 { @@ -41,16 +53,19 @@ func main() { if n / i < i { continue; } + workers := 0 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) + workCh <-work{ i, j, jnext } + workers++ p-- } - markGroup.Wait() + for k := 0; k < workers; k++ { + _ = <-resultCh + } } } d := time.Since(t0)