Skip to content

Commit

Permalink
[performance] update go-structr and go-mutexes with memory usage impr…
Browse files Browse the repository at this point in the history
…ovements (superseriousbusiness#2909)

* update go-structr and go-mutexes with memory usage improvements

* bump to go-structr v0.8.4
  • Loading branch information
NyaaaWhatsUpDoc authored and nyarla committed Jun 19, 2024
1 parent 34dd810 commit e982b55
Show file tree
Hide file tree
Showing 26 changed files with 1,408 additions and 162 deletions.
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
module github.com/superseriousbusiness/gotosocial

go 1.22
go 1.22.2

replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.9-concurrency-workaround

toolchain go1.22.2

require (
codeberg.org/gruf/go-bytes v1.0.2
codeberg.org/gruf/go-bytesize v1.0.2
Expand All @@ -18,11 +16,12 @@ require (
codeberg.org/gruf/go-kv v1.6.4
codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f
codeberg.org/gruf/go-logger/v2 v2.2.1
codeberg.org/gruf/go-mutexes v1.4.1
codeberg.org/gruf/go-mempool v0.0.0-20240507125005-cef10d64a760
codeberg.org/gruf/go-mutexes v1.5.0
codeberg.org/gruf/go-runners v1.6.2
codeberg.org/gruf/go-sched v1.2.3
codeberg.org/gruf/go-store/v2 v2.2.4
codeberg.org/gruf/go-structr v0.8.2
codeberg.org/gruf/go-structr v0.8.4
codeberg.org/superseriousbusiness/exif-terminator v0.7.0
github.com/DmitriyVTitov/size v1.5.0
github.com/KimMachineGun/automemlimit v0.6.0
Expand Down Expand Up @@ -107,6 +106,8 @@ require (
github.com/cornelk/hashmap v1.0.8 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dolthub/maphash v0.1.0 // indirect
github.com/dolthub/swiss v0.2.1 // indirect
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b // indirect
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 // indirect
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
Expand Down
14 changes: 10 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,18 @@ codeberg.org/gruf/go-mangler v1.3.0 h1:cf0vuuLJuEhoIukPHj+MUBIQSWxZcfEYt2Eo/r7Rs
codeberg.org/gruf/go-mangler v1.3.0/go.mod h1:jnOA76AQoaO2kTHi0DlTTVaFYfRM+9fzs8f4XO6MsOk=
codeberg.org/gruf/go-maps v1.0.3 h1:VDwhnnaVNUIy5O93CvkcE2IZXnMB1+IJjzfop9V12es=
codeberg.org/gruf/go-maps v1.0.3/go.mod h1:D5LNDxlC9rsDuVQVM6JObaVGAdHB6g2dTdOdkh1aXWA=
codeberg.org/gruf/go-mutexes v1.4.1 h1:SgsuktbbrkKYmgZ1reA5jMGEZbXJ6GQ54fSlKRN5iug=
codeberg.org/gruf/go-mutexes v1.4.1/go.mod h1:1j/6/MBeBQUedAtAtysLLnBKogfOZAxdym0E3wlaBD8=
codeberg.org/gruf/go-mempool v0.0.0-20240507125005-cef10d64a760 h1:m2/UCRXhjDwAg4vyji6iKCpomKw6P4PmBOUi5DvAMH4=
codeberg.org/gruf/go-mempool v0.0.0-20240507125005-cef10d64a760/go.mod h1:E3RcaCFNq4zXpvaJb8lfpPqdUAmSkP5F1VmMiEUYTEk=
codeberg.org/gruf/go-mutexes v1.5.0 h1:kDegqA/FYQhcn294zUJ3U3VBegfvhtcI7ObcAku1zkw=
codeberg.org/gruf/go-mutexes v1.5.0/go.mod h1:rPEqQ/y6CmGITaZ3GPTMQVsoZAOzbsAHyIaLsJcOqVE=
codeberg.org/gruf/go-runners v1.6.2 h1:oQef9niahfHu/wch14xNxlRMP8i+ABXH1Cb9PzZ4oYo=
codeberg.org/gruf/go-runners v1.6.2/go.mod h1:Tq5PrZ/m/rBXbLZz0u5if+yP3nG5Sf6S8O/GnyEePeQ=
codeberg.org/gruf/go-sched v1.2.3 h1:H5ViDxxzOBR3uIyGBCf0eH8b1L8wMybOXcdtUUTXZHk=
codeberg.org/gruf/go-sched v1.2.3/go.mod h1:vT9uB6KWFIIwnG9vcPY2a0alYNoqdL1mSzRM8I+PK7A=
codeberg.org/gruf/go-store/v2 v2.2.4 h1:8HO1Jh2gg7boQKA3hsDAIXd9zwieu5uXwDXEcTOD9js=
codeberg.org/gruf/go-store/v2 v2.2.4/go.mod h1:zI4VWe5CpXAktYMtaBMrgA5QmO0sQH53LBRvfn1huys=
codeberg.org/gruf/go-structr v0.8.2 h1:0zH5HuOZWTVOGqIq8o5W1jRi944CQWdPXUWZfKUbF0o=
codeberg.org/gruf/go-structr v0.8.2/go.mod h1:K1FXkUyO6N/JKt8aWqyQ8rtW7Z9ZmXKWP8mFAQ2OJjE=
codeberg.org/gruf/go-structr v0.8.4 h1:2eT1VOTWG6T9gIGZwF/1Jop6k6plvfdUY5yBcvbizVg=
codeberg.org/gruf/go-structr v0.8.4/go.mod h1:c5UvVDSA3lZ1kv05V+7pXkO8u8Jea+VRWFDRFBCOxSA=
codeberg.org/superseriousbusiness/exif-terminator v0.7.0 h1:Y6VApSXhKqExG0H2hZ2JelRK4xmWdjDQjn13CpEfzko=
codeberg.org/superseriousbusiness/exif-terminator v0.7.0/go.mod h1:gCWKduudUWFzsnixoMzu0FYVdxHWG+AbXnZ50DqxsUE=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
Expand Down Expand Up @@ -148,6 +150,10 @@ github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ=
github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4=
github.com/dolthub/swiss v0.2.1 h1:gs2osYs5SJkAaH5/ggVJqXQxRXtWshF6uE0lgR/Y3Gw=
github.com/dolthub/swiss v0.2.1/go.mod h1:8AhKZZ1HK7g18j7v7k6c5cYIGEZJcPn0ARsai8cUrh0=
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
github.com/dsoprea/go-exif/v3 v3.0.0-20210428042052-dca55bf8ca15/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
Expand Down
79 changes: 18 additions & 61 deletions internal/queue/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,28 @@ package queue
import (
"context"
"sync"
"unsafe"

"codeberg.org/gruf/go-list"
"codeberg.org/gruf/go-mempool"
)

// frequency of GC cycles
// per no. unlocks. i.e.
// every 'gcfreq' unlocks.
const gcfreq = 1024

// SimpleQueue provides a simple concurrency safe
// queue using generics and a memory pool of list
// elements to reduce overall memory usage.
type SimpleQueue[T any] struct {
l list.List[T]
p elemPool[T]
p mempool.UnsafePool
w chan struct{}
m sync.Mutex
n uint32 // pop counter (safely wraps around)
}

// Push will push given value to the queue.
func (q *SimpleQueue[T]) Push(value T) {
q.m.Lock()

// Wrap in element.
elem := q.p.alloc()
elem := q.acquire()
elem.Value = value

// Push new elem to queue.
Expand Down Expand Up @@ -75,14 +71,7 @@ func (q *SimpleQueue[T]) Pop() (value T, ok bool) {

// Remove tail.
q.l.Remove(tail)
q.p.free(tail)

// Every 'gcfreq' pops perform
// a garbage collection to keep
// us squeaky clean :]
if q.n++; q.n%gcfreq == 0 {
q.p.GC()
}
q.release(tail)
}

q.m.Unlock()
Expand Down Expand Up @@ -134,14 +123,7 @@ func (q *SimpleQueue[T]) PopCtx(ctx context.Context) (value T, ok bool) {

// Remove element.
q.l.Remove(elem)
q.p.free(elem)

// Every 'gcfreq' pops perform
// a garbage collection to keep
// us squeaky clean :]
if q.n++; q.n%gcfreq == 0 {
q.p.GC()
}
q.release(elem)

// Done with lock.
q.m.Unlock()
Expand All @@ -157,45 +139,20 @@ func (q *SimpleQueue[T]) Len() int {
return l
}

// elemPool is a very simple
// list.Elem[T] memory pool.
type elemPool[T any] struct {
current []*list.Elem[T]
victim []*list.Elem[T]
}

func (p *elemPool[T]) alloc() *list.Elem[T] {
// First try the current queue
if l := len(p.current) - 1; l >= 0 {
mu := p.current[l]
p.current = p.current[:l]
return mu
}

// Next try the victim queue.
if l := len(p.victim) - 1; l >= 0 {
mu := p.victim[l]
p.victim = p.victim[:l]
return mu
// acquire will acquire list elem from pool, else alloc new.
func (q *SimpleQueue[T]) acquire() *list.Elem[T] {
if ptr := q.p.Get(); ptr != nil {
return (*list.Elem[T])(ptr)
}

// Lastly, alloc new.
mu := new(list.Elem[T])
return mu
return new(list.Elem[T])
}

// free will release given element to pool.
func (p *elemPool[T]) free(elem *list.Elem[T]) {
// release will reset list elem and release to pool.
func (q *SimpleQueue[T]) release(e *list.Elem[T]) {
var zero T
elem.Next = nil
elem.Prev = nil
elem.Value = zero
p.current = append(p.current, elem)
}

// GC will clear out unused entries from the elemPool.
func (p *elemPool[T]) GC() {
current := p.current
p.current = nil
p.victim = current
e.Next = nil
e.Prev = nil
e.Value = zero
ptr := unsafe.Pointer(e)
q.p.Put(ptr)
}
9 changes: 9 additions & 0 deletions vendor/codeberg.org/gruf/go-mempool/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/codeberg.org/gruf/go-mempool/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions vendor/codeberg.org/gruf/go-mempool/pool.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e982b55

Please sign in to comment.