modified the integrated profiler to hopefully produce more reliable results
This commit is contained in:
parent
1386592aab
commit
f75d11193a
2 changed files with 35 additions and 28 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nim's Runtime Library
|
# Nim's Runtime Library
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -117,24 +117,38 @@ when defined(memProfiler):
|
||||||
var
|
var
|
||||||
gTicker {.threadvar.}: int
|
gTicker {.threadvar.}: int
|
||||||
|
|
||||||
proc hook(st: StackTrace, size: int) {.nimcall.} =
|
proc requestedHook(): bool {.nimcall.} =
|
||||||
if gTicker == 0:
|
if gTicker == 0:
|
||||||
gTicker = -1
|
gTicker = SamplingInterval
|
||||||
|
result = true
|
||||||
|
dec gTicker
|
||||||
|
|
||||||
|
proc hook(st: StackTrace, size: int) {.nimcall.} =
|
||||||
when defined(ignoreAllocationSize):
|
when defined(ignoreAllocationSize):
|
||||||
hookAux(st, 1)
|
hookAux(st, 1)
|
||||||
else:
|
else:
|
||||||
hookAux(st, size)
|
hookAux(st, size)
|
||||||
gTicker = SamplingInterval
|
|
||||||
dec gTicker
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
t0 {.threadvar.}: Ticks
|
t0 {.threadvar.}: Ticks
|
||||||
|
gTicker: int # we use an additional counter to
|
||||||
|
# avoid calling 'getTicks' too frequently
|
||||||
|
|
||||||
|
proc requestedHook(): bool {.nimcall.} =
|
||||||
|
if interval == 0: result = true
|
||||||
|
elif gTicker == 0:
|
||||||
|
gTicker = 500
|
||||||
|
if getTicks() - t0 > interval:
|
||||||
|
result = true
|
||||||
|
else:
|
||||||
|
dec gTicker
|
||||||
|
|
||||||
proc hook(st: StackTrace) {.nimcall.} =
|
proc hook(st: StackTrace) {.nimcall.} =
|
||||||
|
#echo "profiling! ", interval
|
||||||
if interval == 0:
|
if interval == 0:
|
||||||
hookAux(st, 1)
|
hookAux(st, 1)
|
||||||
elif int64(t0) == 0 or getTicks() - t0 > interval:
|
else:
|
||||||
hookAux(st, 1)
|
hookAux(st, 1)
|
||||||
t0 = getTicks()
|
t0 = getTicks()
|
||||||
|
|
||||||
|
|
@ -145,9 +159,10 @@ proc cmpEntries(a, b: ptr ProfileEntry): int =
|
||||||
result = b.getTotal - a.getTotal
|
result = b.getTotal - a.getTotal
|
||||||
|
|
||||||
proc `//`(a, b: int): string =
|
proc `//`(a, b: int): string =
|
||||||
result = format("$1/$2 = $3%", a, b, formatFloat(a / b * 100.0, ffDefault, 2))
|
result = format("$1/$2 = $3%", a, b, formatFloat(a / b * 100.0, ffDecimal, 2))
|
||||||
|
|
||||||
proc writeProfile() {.noconv.} =
|
proc writeProfile() {.noconv.} =
|
||||||
|
system.profilingRequestedHook = nil
|
||||||
when declared(system.StackTrace):
|
when declared(system.StackTrace):
|
||||||
system.profilerHook = nil
|
system.profilerHook = nil
|
||||||
const filename = "profile_results.txt"
|
const filename = "profile_results.txt"
|
||||||
|
|
@ -193,12 +208,12 @@ var
|
||||||
proc disableProfiling*() =
|
proc disableProfiling*() =
|
||||||
when declared(system.StackTrace):
|
when declared(system.StackTrace):
|
||||||
atomicDec disabled
|
atomicDec disabled
|
||||||
system.profilerHook = nil
|
system.profilingRequestedHook = nil
|
||||||
|
|
||||||
proc enableProfiling*() =
|
proc enableProfiling*() =
|
||||||
when declared(system.StackTrace):
|
when declared(system.StackTrace):
|
||||||
if atomicInc(disabled) >= 0:
|
if atomicInc(disabled) >= 0:
|
||||||
system.profilerHook = hook
|
system.profilingRequestedHook = requestedHook
|
||||||
|
|
||||||
when declared(system.StackTrace):
|
when declared(system.StackTrace):
|
||||||
system.profilerHook = hook
|
system.profilerHook = hook
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,15 @@ proc captureStackTrace(f: PFrame, st: var StackTrace) =
|
||||||
inc(i)
|
inc(i)
|
||||||
b = b.prev
|
b = b.prev
|
||||||
|
|
||||||
|
var
|
||||||
|
profilingRequestedHook*: proc (): bool {.nimcall, benign.}
|
||||||
|
## set this variable to provide a procedure that implements a profiler in
|
||||||
|
## user space. See the `nimprof` module for a reference implementation.
|
||||||
|
|
||||||
when defined(memProfiler):
|
when defined(memProfiler):
|
||||||
type
|
type
|
||||||
MemProfilerHook* = proc (st: StackTrace, requestedSize: int) {.nimcall, benign.}
|
MemProfilerHook* = proc (st: StackTrace, requestedSize: int) {.nimcall, benign.}
|
||||||
{.deprecated: [TMemProfilerHook: MemProfilerHook].}
|
|
||||||
var
|
var
|
||||||
profilerHook*: MemProfilerHook
|
profilerHook*: MemProfilerHook
|
||||||
## set this variable to provide a procedure that implements a profiler in
|
## set this variable to provide a procedure that implements a profiler in
|
||||||
|
|
@ -65,17 +70,13 @@ when defined(memProfiler):
|
||||||
hook(st, requestedSize)
|
hook(st, requestedSize)
|
||||||
|
|
||||||
proc nimProfile(requestedSize: int) =
|
proc nimProfile(requestedSize: int) =
|
||||||
if not isNil(profilerHook):
|
if not isNil(profilingRequestedHook) and profilingRequestedHook():
|
||||||
callProfilerHook(profilerHook, requestedSize)
|
callProfilerHook(profilerHook, requestedSize)
|
||||||
else:
|
else:
|
||||||
const
|
|
||||||
SamplingInterval = 50_000
|
|
||||||
# set this to change the default sampling interval
|
|
||||||
var
|
var
|
||||||
profilerHook*: ProfilerHook
|
profilerHook*: ProfilerHook
|
||||||
## set this variable to provide a procedure that implements a profiler in
|
## set this variable to provide a procedure that implements a profiler in
|
||||||
## user space. See the `nimprof` module for a reference implementation.
|
## user space. See the `nimprof` module for a reference implementation.
|
||||||
gTicker {.threadvar.}: int
|
|
||||||
|
|
||||||
proc callProfilerHook(hook: ProfilerHook) {.noinline.} =
|
proc callProfilerHook(hook: ProfilerHook) {.noinline.} =
|
||||||
# 'noinline' so that 'nimProfile' does not perform the stack allocation
|
# 'noinline' so that 'nimProfile' does not perform the stack allocation
|
||||||
|
|
@ -86,16 +87,7 @@ else:
|
||||||
|
|
||||||
proc nimProfile() =
|
proc nimProfile() =
|
||||||
## This is invoked by the compiler in every loop and on every proc entry!
|
## This is invoked by the compiler in every loop and on every proc entry!
|
||||||
if gTicker == 0:
|
if not isNil(profilingRequestedHook) and profilingRequestedHook():
|
||||||
gTicker = -1
|
callProfilerHook(profilerHook)
|
||||||
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
|
|
||||||
dec gTicker
|
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue