smutex

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2021 License: MIT Imports: 1 Imported by: 1

README

kelindar/smutex
Go Version PkgGoDev Go Report Card License Coverage

Sharded Mutex in Go

This package contains a sharded mutex which should do better than a traditional sync.RWMutex in certain cases where you want to protect resources that are well distributed. For example, you can use this to protect a hash table as keys have no relation to each other. That being said, for the hash table use-case you should probably use sync.Map.

The SMutex128 works by actually creating 128 sync.RWMutex and providing Lock(), Unlock() methods that accept a shard argument. A shard argument can overflow the actual number of shards, and mutex uses a modulus operation to wrap around.

// Acquire a write lock for shard #1
mu.Lock(1)
resourceInShard1 = "hello"

// Release the lock in shard #1
mu.Unlock(1)

Caveats

  • Sharded mutex would use significantly more memory and needs to be used with care. In fact, the 128 shard implementation would use 8192 bytes of memory, and would ideally be living in L1. The reason being is that the current implementation pads mutexes so only one of them is present in a cache line, to prevent false sharing.
  • Do benchmark on your own use-case if you want to use this library, I found that in certain cases the current implementation does not perform very well, but need to investigate a bit more. It's usually on-par with the RWMutex at the very least.

Benchmarks

cpu: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
BenchmarkLock/single/procs=64-8                    64495            184600 ns/op
BenchmarkLock/single/procs=256-8                   75350            161236 ns/op
BenchmarkLock/single/procs=1024-8                  85765            161982 ns/op
BenchmarkLock/single/procs=4096-8                  86328            160925 ns/op
BenchmarkLock/single/procs=16384-8                 85803            153741 ns/op
BenchmarkLock/single/procs=65536-8                 85806            152246 ns/op
BenchmarkLock/sharded/procs=64-8                  342633             35435 ns/op
BenchmarkLock/sharded/procs=256-8                 390313             30818 ns/op
BenchmarkLock/sharded/procs=1024-8                416959             30493 ns/op
BenchmarkLock/sharded/procs=4096-8                443528             30246 ns/op
BenchmarkLock/sharded/procs=16384-8               427383             30118 ns/op
BenchmarkLock/sharded/procs=65536-8               451612             30922 ns/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SMutex128

type SMutex128 struct {
	// contains filtered or unexported fields
}

SMutex128 represents a sharded RWMutex that supports finer-granularity concurrency contron hence reducing potential contention.

func (*SMutex128) Lock

func (rw *SMutex128) Lock(shard uint)

Lock locks rw for writing. If the lock is already locked for reading or writing, then Lock blocks until the lock is available.

func (*SMutex128) RLock

func (rw *SMutex128) RLock(shard uint)

RLock locks rw for reading. It should not be used for recursive read locking; a blocked Lock call excludes new readers from acquiring the lock.

func (*SMutex128) RUnlock

func (rw *SMutex128) RUnlock(shard uint)

RUnlock undoes a single RLock call and does not affect other simultaneous readers.

func (*SMutex128) Unlock

func (rw *SMutex128) Unlock(shard uint)

Unlock unlocks rw for writing. It is a run-time error if rw is not locked for writing on entry to Unlock.

Jump to

Keyboard shortcuts

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