galloc is a Pure Go O(1) offset allocator for GPU memory sub-allocation. It is part of the GoGPU ecosystem.
It manages a contiguous range of offsets (e.g., a GPU heap or buffer) and hands out sub-regions with O(1) allocation, O(1) free, and automatic neighbor coalescing. Zero CGO, zero dependencies, zero heap allocations on the hot path.
Based on Sebastian Aaltonen's OffsetAllocator (C++, MIT).
a := galloc.New(64*1024*1024, 4096) // 64 MB, up to 4096 allocations
alloc := a.Allocate(256)
if alloc.Failed() {
// handle OOM
}
// use alloc.Offset
a.Free(alloc)
// GPU-aligned allocation (e.g., 256-byte for Vulkan uniform buffers)
aligned := a.AllocateAligned(4096, 256)
// aligned.Offset % 256 == 0
a.Free(aligned)For concurrent use: galloc.NewSync(size, maxAllocs).
galloc.go -- Allocator core: Allocate, AllocateAligned, Free, coalescing, bin management
smallfloat.go -- SmallFloat uint-to-bin encoding (256 bins, 3-bit mantissa)
sync.go -- SyncAllocator (mutex-wrapped Allocator + AllocateAligned)
doc.go -- Package documentation
- Two-level bitfield (
usedBinsTopuint32 +usedBins[32]uint8) -- O(1) bin lookup viabits.TrailingZeros - Node pool (
[]node, pre-allocated) -- freelist stack, zero heap allocs - Neighbor list (doubly-linked per node) -- spatial adjacency for coalescing
- Bin list (singly-linked per bin) -- free regions within same size class
NoSpace = 0xFFFFFFFF-- sentinel for failed allocationnumLeafBins = 256-- total size classes- Max overhead per allocation: 12.5% (1/8, from 3-bit mantissa)
- GPU buffer sub-allocation (VkBuffer, ID3D12Resource heaps)
- Ring buffer offset management (staging belts)
- Any contiguous-range sub-allocation needing O(1) performance
galloc is consumed by gogpu/wgpu HAL backends for GPU memory management. It has zero dependencies and can be used standalone.
| Repo | Relationship |
|---|---|
| wgpu | Consumer -- HAL memory sub-allocation |
| gogpu | Parent ecosystem |
go build ./... # Build
go test ./... # Test
go test -bench=. -benchmem # Benchmark
go test -fuzz=FuzzAllocFree # Fuzz
golangci-lint run --timeout=5m # Lint