Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set maps above a certain size #2

Closed
nightwolfz opened this issue Aug 28, 2022 · 7 comments
Closed

Cannot set maps above a certain size #2

nightwolfz opened this issue Aug 28, 2022 · 7 comments

Comments

@nightwolfz
Copy link

go 1.19

func TestMakeHaxmap(t *testing.T) {
	for f := 1; f < 1000000; f *= 5 {
		m := haxmap.New[int, string]()
		t.Logf("creating %d", f)

		for i := 0; i < f; i++ {
			m.Set(i, fmt.Sprintf("a%d", i))
		}

		t.Logf("size: %d", m.Size())
	}
}

Randomly hangs forever...

@alphadose
Copy link
Owner

alphadose commented Aug 28, 2022

Hi @nightwolfz , can you try it with an initial size such as m := haxmap.New[int, string](1 << 12) ?

Also you are allocating the hashmap in each round of the for loop, can you move it outside the loop or is that intentional ?

@nightwolfz
Copy link
Author

@alphadose That's just an example to illustrate the issue.

You can simplify it to

func TestMakeHaxmap(t *testing.T) {
	m := haxmap.New[int, string]()

	for i := 0; i < 65000; i++ {
		m.Set(i, fmt.Sprintf("a%d", i))
	}
	t.Logf("size: %d", m.Size())
}

At test.cpu=1, this hangs indefinitely at around 5500
At test.cpu=2, this hangs around 52000
At test.cpu>2, the test sometimes finishes, sometimes hangs.

If I add runtime.Gosched() to the loop, the issue never shows up. Probably since it gives enough time for the grow goroutine to execute?

If this is by design, it might be worth mentioning in the README.

@alphadose
Copy link
Owner

alphadose commented Aug 29, 2022

@nightwolfz yes rapid map growth via Set() creates a lot of grow() goroutines which causes choking and as you said using runtime.Gosched() frees up the CPU hence more time for the growth.

One of haxmap's future goals is a better growth policy which wont choke and hence there is lots more room for improvement

If this is by design, it might be worth mentioning in the README.

Yes, I will mention it

Also the current workaround for this behaviour would be initializing the map with a good size which will cause lesser grow operations and wont choke

@nightwolfz
Copy link
Author

A few ideas for https://github.com/alphadose/haxmap/blob/main/map.go#L140

  1. Give the goroutine some time.
		if resizeNeeded(uintptr(len(data.index)), count) {
			runtime.Gosched()
			if m.resizing.CompareAndSwap(notResizing, resizingInProgress) {
				go m.grow(0, true)
			}
		}
  1. Or remove the goroutine (and the loop in m.grow) and let it happen sync.
		if resizeNeeded(uintptr(len(data.index)), count) && m.resizing.CompareAndSwap(notResizing, resizingInProgress) {
			m.growSync(0, true)
		}
goos: linux
goarch: amd64
pkg: github.com/alphadose/haxmap/benchmarks
cpu: AMD Ryzen 7 5800X 8-Core Processor             
BenchmarkHaxMapReadsWithWritesX
BenchmarkHaxMapReadsWithWritesX/grow-current
BenchmarkHaxMapReadsWithWritesX/grow-current-4         	  114321	     10393 ns/op	    1976 B/op	     247 allocs/op
BenchmarkHaxMapReadsWithWritesX/grow-sched
BenchmarkHaxMapReadsWithWritesX/grow-sched-4           	  120441	     10284 ns/op	    1977 B/op	     247 allocs/op
BenchmarkHaxMapReadsWithWritesX/grow-sync
BenchmarkHaxMapReadsWithWritesX/grow-sync-4            	  117235	     10278 ns/op	    1987 B/op	     248 allocs/op
PASS

@alphadose
Copy link
Owner

alphadose commented Aug 29, 2022

Yes, this sounds plausible, if possible can you checkout a branch with these changes ? It would be much easier for both of us to test that way.

I like the 2nd option:- letting everything happen in sync

@alphadose
Copy link
Owner

alphadose commented Aug 30, 2022

@nightwolfz I have updated the main branch with this d071dd5

With this commit growth happens synchronously and the benchmarks and tests are passing as well

can you run your tests once again and tell me the results ?

@nightwolfz
Copy link
Author

Much better now.

@alphadose alphadose mentioned this issue Sep 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants