diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-01-19 12:46:49 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-01-19 12:48:39 +0100 |
commit | f7c0360aba4e8ac2857adb85ff838d94cf30ff53 (patch) | |
tree | a14077770c2353680f3cdcaae335f68c2bfd7f6f /lib/system | |
parent | 86a91c1a4a38a669e9ed5409975936f64ad3e532 (diff) | |
download | Nim-f7c0360aba4e8ac2857adb85ff838d94cf30ff53.tar.gz |
allocators: introduce --define:nimMinHeapPages for tuning mmap calls (omg they are slow on OSX...)
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/alloc.nim | 6 | ||||
-rw-r--r-- | lib/system/gc_regions.nim | 29 |
2 files changed, 29 insertions, 6 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index b090117a9..e938dc475 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -20,7 +20,7 @@ template track(op, address, size) = # Each chunk starts at an address that is divisible by the page size. const - InitialMemoryRequest = 128 * PageSize # 0.5 MB + nimMinHeapPages {.intdefine.} = 128 # 0.5 MB SmallChunkSize = PageSize MaxFli = 30 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") result = findSuitableBlock(a, fl, sl) if result == nil: - if size < InitialMemoryRequest: - result = requestOsChunks(a, InitialMemoryRequest) + if size < nimMinHeapPages * PageSize: + result = requestOsChunks(a, nimMinHeapPages * PageSize) splitChunk(a, result, size) else: result = requestOsChunks(a, size) diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim index 8a1446944..3b908fb08 100644 --- a/lib/system/gc_regions.nim +++ b/lib/system/gc_regions.nim @@ -23,6 +23,21 @@ when defined(nimphpext): proc osDeallocPages(p: pointer, size: int) {.inline.} = 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: include osalloc @@ -108,6 +123,8 @@ template `+!`(p: pointer, s: int): pointer = template `-!`(p: pointer, s: int): pointer = cast[pointer](cast[int](p) -% s) +const nimMinHeapPages {.intdefine.} = 4 + proc allocSlowPath(r: var MemRegion; size: int) = # we need to ensure that the underlying linked list # 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, # 16GB --> list contains only 20 elements! That's reasonable. if (r.totalSize and 1) == 0: - r.nextChunkSize = - if r.totalSize < 64 * 1024: PageSize*4 - else: r.nextChunkSize*2 + r.nextChunkSize = if r.totalSize < 64 * 1024: PageSize*nimMinHeapPages + else: r.nextChunkSize*2 var s = roundup(size+sizeof(BaseChunk), PageSize) var fresh: Chunk if s > r.nextChunkSize: @@ -242,6 +258,13 @@ proc deallocAll*() = tlRegion.deallocAll() proc deallocOsPages(r: var MemRegion) = r.deallocAll() template withScratchRegion*(body: untyped) = + let obs = obstackPtr() + try: + body + finally: + setObstackPtr(obs) + +when false: var scratch: MemRegion let oldRegion = tlRegion tlRegion = scratch |