allocators: introduce --define:nimMinHeapPages for tuning mmap calls (omg they are slow on OSX...)
This commit is contained in:
parent
86a91c1a4a
commit
f7c0360aba
2 changed files with 29 additions and 6 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,8 +133,7 @@ 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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue