profiler improvements

This commit is contained in:
Araq
2012-09-17 00:31:41 +02:00
parent ad6ee9e857
commit 75abf72503
8 changed files with 110 additions and 71 deletions

View File

@@ -33,7 +33,7 @@ var
# list of exception handlers
# a global variable for the root of all try blocks
{.push stacktrace: off.}
{.push stacktrace: off, profiler:off.}
proc nimBoolToStr(x: bool): string {.compilerproc.} =
if x: result = "true"
else: result = "false"

View File

@@ -78,11 +78,11 @@ var
when not defined(useNimRtl):
InstantiateForRegion(gch.region)
proc acquire(gch: var TGcHeap) {.inline.} =
template acquire(gch: TGcHeap) =
when hasThreadSupport and hasSharedHeap:
AcquireSys(HeapLock)
proc release(gch: var TGcHeap) {.inline.} =
template release(gch: TGcHeap) =
when hasThreadSupport and hasSharedHeap:
releaseSys(HeapLock)

View File

@@ -18,9 +18,6 @@
{.push profiler: off.}
when not defined(getTicks):
include "system/timers"
const
MaxTraceLen = 20 # tracking the last 20 calls is enough
@@ -36,7 +33,7 @@ proc captureStackTrace(f: PFrame, st: var TStackTrace) =
i = 0
total = 0
while it != nil and i <= high(st)-(firstCalls-1):
# the (-1) is for a nil entry that marks where the '...' should occur
# the (-1) is for the "..." entry
st[i] = it.procname
inc(i)
inc(total)
@@ -55,14 +52,14 @@ proc captureStackTrace(f: PFrame, st: var TStackTrace) =
inc(i)
b = b.prev
const
SamplingInterval = 50_000
# set this to change the default sampling interval
var
profilerHook*: TProfilerHook
## set this variable to provide a procedure that implements a profiler in
## user space. See the `nimprof` module for a reference implementation.
SamplingInterval = 50_000
# set this to change the default sampling interval
gTicker = SamplingInterval
interval: TNanos = 5_000_000 # 5ms
gTicker {.threadvar.}: int
proc callProfilerHook(hook: TProfilerHook) {.noinline.} =
# 'noinline' so that 'nimProfile' does not perform the stack allocation
@@ -71,31 +68,18 @@ proc callProfilerHook(hook: TProfilerHook) {.noinline.} =
captureStackTrace(framePtr, st)
hook(st)
proc setProfilingInterval*(intervalInUs: int): TNanos =
## set this to change the sampling interval. Default value is 5ms.
interval = intervalInUs * 1000
var t0: TTicks
proc nimProfile() =
## This is invoked by the compiler in every loop and on every proc entry!
dec gTicker
if gTicker == 0:
gTicker = -1
let t1 = getticks()
if getticks() - t0 > interval:
if not isNil(profilerHook):
# disable recursive calls: XXX should use try..finally,
# but that's too expensive!
let oldHook = profilerHook
profilerHook = nil
callProfilerHook(oldHook)
profilerHook = oldHook
t0 = getticks()
if not isNil(profilerHook):
# disable recursive calls: XXX should use try..finally,
# but that's too expensive!
let oldHook = profilerHook
profilerHook = nil
callProfilerHook(oldHook)
profilerHook = oldHook
gTicker = SamplingInterval
proc stopProfiling*() =
## call this to stop profiling; should be called by the client profiler.
profilerHook = nil
dec gTicker
{.pop.}

View File

@@ -224,7 +224,7 @@ proc ReadBytes(f: TFile, a: var openarray[int8], start, len: int): int =
proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int =
result = readBuffer(f, addr(a[start]), len)
{.push stackTrace:off.}
{.push stackTrace:off, profiler:off.}
proc writeBytes(f: TFile, a: openarray[int8], start, len: int): int =
var x = cast[ptr array[0..1000_000_000, int8]](a)
result = writeBuffer(f, addr(x[start]), len)