cay

package module
v0.0.0-...-fe485d4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2022 License: MIT Imports: 5 Imported by: 0

README

cay - SIMD-based hashmap for Go.

Note that this is an experimental prototype, so don't use in production

Cay's goal is to be a faster and more memory-efficient replacements for the builtin map in Go.

Cay is heavily inspired by the Hashbrown map in Rust (which in turn is a port of the Swisstable)

As this is my first real endevaour in the world of memory operations and optimizations in Go, I have included my log of my (mostly failed) experimentation.

Developing on caymap

To start:
  • go get -u github.com/minio/asm2plan9s
Developing

To rebuild the ASM files from the c code:

./build.sh
Running

To run the benchmarks:

go test -run=^\$ -cpu 1 -bench '.*' --benchmem

Checking the profile

go tool pprof   --http :1234 caymap.test cpu.profile
Debugging
  • go tool objdump -s find caymap.test inspecting bytecode

  • go build -gcflags '-m -m' .

Using perf

Build the caymap tests for linux:

  • env GOOS=linux GOARCH=amd64 go test -c -o caymap.test

Record the instructions:

./perf record -e dTLB-load-misses -g ./caymap.test -test.run=^\$ -test.cpu 1 -test.benchmem -test.benchtime 10000000x -test.bench '.*simd.*get/same_keys.*'

View

./perf annotate --stdio -l --tui
Using Instruments

To use Instruments, first compile the test binary:

# From the simdmap dir
go test -c -o caymap.test

Then open instruments and use the caymap.test file as the target. For arguments you can pass in

-test.run=^\$ -test.cpu 1 -test.benchmem -test.benchtime 10000000x -test.bench '.*not_found/dynamic_keys.*'

and that will run each the not found benchmarks 10,000,000 times. Change the regexp for the other benchmarks.

TODO

  • Compare memory footprint of caymap and builtin.
  • HighestBitMask has a tendency to crash, unless ctrlGroup is allocated on the heap. My best guess is that it is otherwise not stack aligned (some architectures require 16-byte aligned stacks).
  • Returning the element in Get is costing 33% of the overall runtime and might be some locality or copying that is expensive.
  • Investigate tuning huge pages and transparent huge pages on.
  • Investigate page alignment

References

HashBrown and SwissTable
Bit operations
Calling ASM in Go

Documentation

Index

Constants

View Source
const (
	PtrSize = 4 << (^uintptr(0) >> 63)
)

Variables

This section is empty.

Functions

func CompareNMask

func CompareNMask(ctrlGroup [_slotsPerGroup]byte, mask byte) uint16

func HighestBitMask

func HighestBitMask(ctrlGroup [_slotsPerGroup]byte) uint16

func RandomKeys

func RandomKeys(size int) []string

func RandomKeysWithSuffix

func RandomKeysWithSuffix(size int, suffix string) []string

Types

type Map

type Map[V any] struct {
	// contains filtered or unexported fields
}

func NewMap

func NewMap[V any](size int) *Map[V]

NewMap creates a new caymap initialized with the given size and given value type.

func Simdmap

func Simdmap(keys []string) *Map[[]byte]

func (*Map[V]) Get

func (m *Map[V]) Get(key string) (V, bool)

Get returns the entry with the given key and a bool if the key was found.

func (*Map[V]) Insert

func (m *Map[V]) Insert(key string, value V)

Directories

Path Synopsis
z

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL