81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
// Run SMA(20) batch over a panel of assets, serial vs goroutine fan-out, and
|
|||
|
|
// report the speedup.
|
||
|
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"runtime"
|
||
|
|
"strconv"
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
wickra "github.com/wickra-lib/wickra/bindings/go"
|
||
|
|
"github.com/wickra-lib/wickra/examples/go/internal/market"
|
||
|
|
)
|
||
|
|
|
||
|
|
func main() {
|
||
|
|
assets := argInt(1, 500)
|
||
|
|
bars := argInt(2, 20_000)
|
||
|
|
|
||
|
|
panel := make([][]float64, assets)
|
||
|
|
for a := 0; a < assets; a++ {
|
||
|
|
panel[a] = market.SyntheticPricesFrom(bars, 50.0+float64(a)*0.1)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Warm up so the comparison is fair.
|
||
|
|
if warm, err := wickra.NewSma(20); err == nil {
|
||
|
|
warm.Batch(panel[0])
|
||
|
|
warm.Close()
|
||
|
|
}
|
||
|
|
|
||
|
|
sink := 0.0
|
||
|
|
start := time.Now()
|
||
|
|
for a := 0; a < assets; a++ {
|
||
|
|
sma, _ := wickra.NewSma(20)
|
||
|
|
result := sma.Batch(panel[a])
|
||
|
|
sma.Close()
|
||
|
|
sink += result[len(result)-1]
|
||
|
|
}
|
||
|
|
serial := time.Since(start)
|
||
|
|
|
||
|
|
lasts := make([]float64, assets)
|
||
|
|
start = time.Now()
|
||
|
|
var wg sync.WaitGroup
|
||
|
|
work := make(chan int, assets)
|
||
|
|
for w := 0; w < runtime.GOMAXPROCS(0); w++ {
|
||
|
|
wg.Add(1)
|
||
|
|
go func() {
|
||
|
|
defer wg.Done()
|
||
|
|
for a := range work {
|
||
|
|
sma, _ := wickra.NewSma(20)
|
||
|
|
result := sma.Batch(panel[a])
|
||
|
|
sma.Close()
|
||
|
|
lasts[a] = result[len(result)-1]
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
}
|
||
|
|
for a := 0; a < assets; a++ {
|
||
|
|
work <- a
|
||
|
|
}
|
||
|
|
close(work)
|
||
|
|
wg.Wait()
|
||
|
|
parallel := time.Since(start)
|
||
|
|
|
||
|
|
serialMs := float64(serial.Microseconds()) / 1000.0
|
||
|
|
parallelMs := float64(parallel.Microseconds()) / 1000.0
|
||
|
|
fmt.Printf("%d assets x %d bars, SMA(20) batch:\n", assets, bars)
|
||
|
|
fmt.Printf(" serial %8.1f ms\n", serialMs)
|
||
|
|
fmt.Printf(" parallel %8.1f ms (%.1fx speedup)\n", parallelMs, serialMs/max(parallelMs, 1e-9))
|
||
|
|
_ = sink
|
||
|
|
}
|
||
|
|
|
||
|
|
func argInt(i, def int) int {
|
||
|
|
if len(os.Args) > i {
|
||
|
|
if v, err := strconv.Atoi(os.Args[i]); err == nil {
|
||
|
|
return v
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return def
|
||
|
|
}
|