type WorkerPool struct {
// contains filtered or unexported fields
} Create it with NewWorkerPool, reuse it across calls, and release it with WorkerPool.Close.
WorkerPool provides pre-pinned goroutines with pre-configured SIMD state.
Create once, reuse across batch calls, close when done.
The pool amortizes Device.ConfigureThread + LockOSThread cost across all batch operations.
package main
import (
"fmt"
nk "github.com/ashvardanian/NumKong/golang"
)
func main() {
columns, depth, totalQueries := 1024, 128, 10000
db := make([]float32, columns*depth)
queries := make([]float32, totalQueries*depth)
for i := range db { db[i] = float32(i%7) * 0.1 }
for i := range queries { queries[i] = float32(i%11) * 0.1 }
dbPacked := nk.NewDotsPackedMatrixF32(db, columns, depth)
// Create a reusable pool (defaults to GOMAXPROCS workers)
pool := nk.NewWorkerPool(8)
defer pool.Close()
// Packed batch operations dispatch to the pool
results := make([]float64, totalQueries*columns)
dbPacked.DotsF32WithPool(queries, results, totalQueries, pool)
// Angular and Euclidean distances use the same pool
angResults := make([]float64, totalQueries*columns)
dbPacked.AngularsF32WithPool(queries, angResults, totalQueries, pool)
fmt.Println("first result row:", results[:columns])
}Symmetric operations also support pool-based parallelism:
n, depth := 1000, 128
vectors := make([]float32, n*depth)
gram := make([]float64, n*n)
pool := nk.NewWorkerPool(0) // 0 = GOMAXPROCS
defer pool.Close()
nk.DotsSymmetricF32WithPool(vectors, n, depth, gram, pool)For one-off parallel work without a pool, you can still use ConfigureThread directly:
go func() {
enabled, _ := nk.CPU().CapabilitiesEnabled()
unlock, _ := nk.CPU().ConfigureThread(enabled) // lock thread + configure SIMD
defer unlock() // release the OS thread on return
nk.DotsPackedF32(queries, dbPacked, results, rows)
}()WorkerPoolWorkerPool runs batch kernels on goroutines pinned to OS threads, each configuring its SIMD state once.3type WorkerPool struct {
// contains filtered or unexported fields
} Create it with NewWorkerPool, reuse it across calls, and release it with WorkerPool.Close.
NewWorkerPoolNewWorkerPool starts n pinned workers, or GOMAXPROCS workers when n is not positive.func NewWorkerPool(n int) *WorkerPool CloseClose stops every worker and waits for it to exit.func (p *WorkerPool) Close() SizeSize returns the number of workers in the pool.func (p *WorkerPool) Size() int