Skip to content

Instantly share code, notes, and snippets.

@bohdantrotsenko
Created November 25, 2020 10:13
Show Gist options
  • Save bohdantrotsenko/6f6c7ee1d5345d82f5f678ebf5b23076 to your computer and use it in GitHub Desktop.
Save bohdantrotsenko/6f6c7ee1d5345d82f5f678ebf5b23076 to your computer and use it in GitHub Desktop.
A primitive cpu test
package main
import (
"fmt"
"log"
"runtime"
"time"
"golang.org/x/crypto/scrypt"
)
const ITER = 5
func workItem() {
_, err := scrypt.Key([]byte("password"), []byte("NaCl"), 64, 8, 16, 64)
if err != nil {
log.Fatal("Incorrect usage of scrypt()")
}
}
func measure(n int64) time.Duration {
start := time.Now()
for i := int64(0); i < n; i++ {
workItem()
}
return time.Now().Sub(start)
}
func getMax(arr []float64) float64 {
best := 0.0
for _, el := range arr {
if el > best {
best = el
}
}
return best
}
func opt() int64 {
n := int64(1)
var t time.Duration
for {
fmt.Printf("%d... ", n)
t = measure(n)
if t < time.Second {
n = n * 2
} else {
break
}
}
fmt.Println()
fmt.Printf("Optimal: %d cycles in %f seconds\n", n, t.Seconds())
series := make([]float64, ITER)
series[0] = (float64(n)) / t.Seconds()
fmt.Printf("Rate: %f\n", series[0])
for i := 1; i < ITER; i++ {
t = measure(n)
series[i] = (float64(n)) / t.Seconds()
fmt.Printf("Rate: %f\n", series[i])
}
fmt.Println("---------------")
best := getMax(series)
fmt.Printf("Best: %f\n", best)
return n
}
func workerParallel(res chan time.Time) {
for {
workItem()
res <- time.Now()
}
}
func optParallel(n int64, coresNo int) {
resChan := make(chan time.Time)
start := time.Now()
target := int64(coresNo) * n
if target < 0 {
fmt.Println("CPUs is too weak for a parallel test")
return
}
for i := 0; i < coresNo; i++ {
go workerParallel(resChan)
}
var end time.Time
for i := int64(0); i < target; i++ {
end = <-resChan
}
dur_s := end.Sub(start).Seconds()
rate := float64(target) / dur_s
fmt.Printf("Parallel rate: %f (reached %d in %f seconds)\n", rate, target, dur_s)
}
func main() {
coresNo := runtime.GOMAXPROCS(0)
bestFor1Core := opt()
fmt.Printf("Trying on %d cores.\n", coresNo)
runtime.GOMAXPROCS(coresNo)
optParallel(bestFor1Core, coresNo)
}
@bketelsen
Copy link

1... 2... 4... 8... 16... 32... 64... 128... 256... 512... 1024...
Optimal: 1024 cycles in 1.719771 seconds
Rate: 595.428126
Rate: 597.526000
Rate: 597.129899
Rate: 597.220983
Rate: 596.430909
---------------
Best: 597.526000
Trying on 8 cores.
Parallel rate: 2844.318195 (reached 8192 in 2.880128 seconds)```

@bketelsen
Copy link

interesting. my i7 nuc numbers:

1... 2... 4... 8... 16... 32... 64... 128... 256... 512...
Optimal: 512 cycles in 1.490006 seconds
Rate: 343.622874
Rate: 342.948417
Rate: 344.113067
Rate: 340.702616
Rate: 343.756507
---------------
Best: 344.113067
Trying on 8 cores.
Parallel rate: 1489.097516 (reached 4096 in 2.750659 seconds)```

@bohdantrotsenko
Copy link
Author

mac 2018, 2,3 GHz Quad-Core Intel Core i5

Optimal: 512 cycles in 1.377254 seconds
Rate: 371.754173
Rate: 383.288999
Rate: 381.448414
Rate: 384.611823
Rate: 382.155367
---------------
Best: 384.611823
Trying on 8 cores.
Parallel rate: 1583.587651 (reached 4096 in 2.586532 seconds)```

@bohdantrotsenko
Copy link
Author

Raspberry Pi 4

Optimal: 128 cycles in 1.401186 seconds
Rate: 91.351160
Rate: 91.358067
Rate: 91.106732
Rate: 91.665454
Rate: 91.575683
---------------
Best: 91.665454
Trying on 4 cores.
Parallel rate: 361.139789 (reached 512 in 1.417734 seconds)```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment