allocators: introduce --define:nimMinHeapPages for tuning mmap calls (omg they are slow on OSX...)

This commit is contained in:
Andreas Rumpf 2019-01-19 12:46:49 +01:00
commit f7c0360aba
2 changed files with 29 additions and 6 deletions

View file

@ -20,7 +20,7 @@ template track(op, address, size) =
# Each chunk starts at an address that is divisible by the page size. # Each chunk starts at an address that is divisible by the page size.
const const
InitialMemoryRequest = 128 * PageSize # 0.5 MB nimMinHeapPages {.intdefine.} = 128 # 0.5 MB
SmallChunkSize = PageSize SmallChunkSize = PageSize
MaxFli = 30 MaxFli = 30
MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32' MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32'
@ -588,8 +588,8 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk =
sysAssert((size and PageMask) == 0, "getBigChunk: unaligned chunk") sysAssert((size and PageMask) == 0, "getBigChunk: unaligned chunk")
result = findSuitableBlock(a, fl, sl) result = findSuitableBlock(a, fl, sl)
if result == nil: if result == nil:
if size < InitialMemoryRequest: if size < nimMinHeapPages * PageSize:
result = requestOsChunks(a, InitialMemoryRequest) result = requestOsChunks(a, nimMinHeapPages * PageSize)
splitChunk(a, result, size) splitChunk(a, result, size)
else: else:
result = requestOsChunks(a, size) result = requestOsChunks(a, size)

View file

@ -23,6 +23,21 @@ when defined(nimphpext):
proc osDeallocPages(p: pointer, size: int) {.inline.} = proc osDeallocPages(p: pointer, size: int) {.inline.} =
efree(p) efree(p)
elif defined(useMalloc):
proc roundup(x, v: int): int {.inline.} =
result = (x + (v-1)) and not (v-1)
proc emalloc(size: int): pointer {.importc: "malloc", header: "<stdlib.h>".}
proc efree(mem: pointer) {.importc: "free", header: "<stdlib.h>".}
proc osAllocPages(size: int): pointer {.inline.} =
emalloc(size)
proc osTryAllocPages(size: int): pointer {.inline.} =
emalloc(size)
proc osDeallocPages(p: pointer, size: int) {.inline.} =
efree(p)
else: else:
include osalloc include osalloc
@ -108,6 +123,8 @@ template `+!`(p: pointer, s: int): pointer =
template `-!`(p: pointer, s: int): pointer = template `-!`(p: pointer, s: int): pointer =
cast[pointer](cast[int](p) -% s) cast[pointer](cast[int](p) -% s)
const nimMinHeapPages {.intdefine.} = 4
proc allocSlowPath(r: var MemRegion; size: int) = proc allocSlowPath(r: var MemRegion; size: int) =
# we need to ensure that the underlying linked list # we need to ensure that the underlying linked list
# stays small. Say we want to grab 16GB of RAM with some # stays small. Say we want to grab 16GB of RAM with some
@ -116,9 +133,8 @@ proc allocSlowPath(r: var MemRegion; size: int) =
# 8MB, 16MB, 32MB, 64MB, 128MB, 512MB, 1GB, 2GB, 4GB, 8GB, # 8MB, 16MB, 32MB, 64MB, 128MB, 512MB, 1GB, 2GB, 4GB, 8GB,
# 16GB --> list contains only 20 elements! That's reasonable. # 16GB --> list contains only 20 elements! That's reasonable.
if (r.totalSize and 1) == 0: if (r.totalSize and 1) == 0:
r.nextChunkSize = r.nextChunkSize = if r.totalSize < 64 * 1024: PageSize*nimMinHeapPages
if r.totalSize < 64 * 1024: PageSize*4 else: r.nextChunkSize*2
else: r.nextChunkSize*2
var s = roundup(size+sizeof(BaseChunk), PageSize) var s = roundup(size+sizeof(BaseChunk), PageSize)
var fresh: Chunk var fresh: Chunk
if s > r.nextChunkSize: if s > r.nextChunkSize:
@ -242,6 +258,13 @@ proc deallocAll*() = tlRegion.deallocAll()
proc deallocOsPages(r: var MemRegion) = r.deallocAll() proc deallocOsPages(r: var MemRegion) = r.deallocAll()
template withScratchRegion*(body: untyped) = template withScratchRegion*(body: untyped) =
let obs = obstackPtr()
try:
body
finally:
setObstackPtr(obs)
when false:
var scratch: MemRegion var scratch: MemRegion
let oldRegion = tlRegion let oldRegion = tlRegion
tlRegion = scratch tlRegion = scratch