84 lines
2.1 KiB
Go
84 lines
2.1 KiB
Go
|
// linear congruential generator written in go
|
||
|
// by darkmage
|
||
|
// https://www.evildojo.com
|
||
|
// https://www.twitter.com/evildojo666
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
"os"
|
||
|
"math"
|
||
|
"math/rand"
|
||
|
"strconv"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
// define a global sieve
|
||
|
var sieve []bool
|
||
|
var wg sync.WaitGroup
|
||
|
|
||
|
|
||
|
func run_sieve(max int64, start int64, move int64, shard_num int64, shard_count int64) {
|
||
|
var current int64 = start + shard_num
|
||
|
if current > max-1 {
|
||
|
current = current % max
|
||
|
}
|
||
|
for i := int64(0); i <= max/shard_count; i++ {
|
||
|
sieve[current] = true
|
||
|
current = current + move
|
||
|
if current > max-1 {
|
||
|
current = current % max
|
||
|
}
|
||
|
}
|
||
|
defer wg.Done()
|
||
|
}
|
||
|
|
||
|
|
||
|
func main() {
|
||
|
if len(os.Args) != 3 {
|
||
|
fmt.Println("Usage: go run main.go <seed> <shard_count>")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
seed, err := strconv.ParseInt(os.Args[1], 10, 64)
|
||
|
if err != nil {
|
||
|
fmt.Println("Error: ", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
rand := rand.New(rand.NewSource(seed))
|
||
|
var max int64 = 256*256*256*256
|
||
|
var start int64 = rand.Int63n(max)
|
||
|
fmt.Println("start:", start)
|
||
|
shard_count, err := strconv.ParseInt(os.Args[2], 10, 64)
|
||
|
if err != nil {
|
||
|
fmt.Println("Error: ", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
fmt.Println("shard_count:", shard_count)
|
||
|
var move int64 = (int64(math.Sqrt(float64(max))) + 1) * shard_count
|
||
|
fmt.Println("move:", move)
|
||
|
sieve = make([]bool, max)
|
||
|
start_time := time.Now()
|
||
|
for i := int64(0); i < shard_count; i++ {
|
||
|
fmt.Println("shard:", i)
|
||
|
wg.Add(1)
|
||
|
go run_sieve(max, start, move, i, shard_count)
|
||
|
}
|
||
|
wg.Wait()
|
||
|
end_time := time.Now()
|
||
|
fmt.Println("Completed iterating numbers")
|
||
|
fmt.Println("Time elapsed:", end_time.Sub(start_time))
|
||
|
fmt.Println("Checking sieve")
|
||
|
start_time = time.Now()
|
||
|
for i := int64(0); i < max; i++ {
|
||
|
if !sieve[i] {
|
||
|
fmt.Println(os.Stderr, "Error, not all numbers flipped")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
}
|
||
|
end_time = time.Now()
|
||
|
fmt.Println("Time elapsed:", end_time.Sub(start_time))
|
||
|
}
|
||
|
|