mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
modified the integrated profiler to hopefully produce more reliable results
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -117,24 +117,38 @@ when defined(memProfiler):
|
||||
var
|
||||
gTicker {.threadvar.}: int
|
||||
|
||||
proc hook(st: StackTrace, size: int) {.nimcall.} =
|
||||
proc requestedHook(): bool {.nimcall.} =
|
||||
if gTicker == 0:
|
||||
gTicker = -1
|
||||
when defined(ignoreAllocationSize):
|
||||
hookAux(st, 1)
|
||||
else:
|
||||
hookAux(st, size)
|
||||
gTicker = SamplingInterval
|
||||
result = true
|
||||
dec gTicker
|
||||
|
||||
proc hook(st: StackTrace, size: int) {.nimcall.} =
|
||||
when defined(ignoreAllocationSize):
|
||||
hookAux(st, 1)
|
||||
else:
|
||||
hookAux(st, size)
|
||||
|
||||
else:
|
||||
var
|
||||
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.} =
|
||||
#echo "profiling! ", interval
|
||||
if interval == 0:
|
||||
hookAux(st, 1)
|
||||
elif int64(t0) == 0 or getTicks() - t0 > interval:
|
||||
else:
|
||||
hookAux(st, 1)
|
||||
t0 = getTicks()
|
||||
|
||||
@@ -145,9 +159,10 @@ proc cmpEntries(a, b: ptr ProfileEntry): int =
|
||||
result = b.getTotal - a.getTotal
|
||||
|
||||
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.} =
|
||||
system.profilingRequestedHook = nil
|
||||
when declared(system.StackTrace):
|
||||
system.profilerHook = nil
|
||||
const filename = "profile_results.txt"
|
||||
@@ -193,12 +208,12 @@ var
|
||||
proc disableProfiling*() =
|
||||
when declared(system.StackTrace):
|
||||
atomicDec disabled
|
||||
system.profilerHook = nil
|
||||
system.profilingRequestedHook = nil
|
||||
|
||||
proc enableProfiling*() =
|
||||
when declared(system.StackTrace):
|
||||
if atomicInc(disabled) >= 0:
|
||||
system.profilerHook = hook
|
||||
system.profilingRequestedHook = requestedHook
|
||||
|
||||
when declared(system.StackTrace):
|
||||
system.profilerHook = hook
|
||||
|
||||
@@ -50,10 +50,15 @@ proc captureStackTrace(f: PFrame, st: var StackTrace) =
|
||||
inc(i)
|
||||
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):
|
||||
type
|
||||
MemProfilerHook* = proc (st: StackTrace, requestedSize: int) {.nimcall, benign.}
|
||||
{.deprecated: [TMemProfilerHook: MemProfilerHook].}
|
||||
|
||||
var
|
||||
profilerHook*: MemProfilerHook
|
||||
## set this variable to provide a procedure that implements a profiler in
|
||||
@@ -65,17 +70,13 @@ when defined(memProfiler):
|
||||
hook(st, requestedSize)
|
||||
|
||||
proc nimProfile(requestedSize: int) =
|
||||
if not isNil(profilerHook):
|
||||
if not isNil(profilingRequestedHook) and profilingRequestedHook():
|
||||
callProfilerHook(profilerHook, requestedSize)
|
||||
else:
|
||||
const
|
||||
SamplingInterval = 50_000
|
||||
# set this to change the default sampling interval
|
||||
var
|
||||
profilerHook*: ProfilerHook
|
||||
## set this variable to provide a procedure that implements a profiler in
|
||||
## user space. See the `nimprof` module for a reference implementation.
|
||||
gTicker {.threadvar.}: int
|
||||
|
||||
proc callProfilerHook(hook: ProfilerHook) {.noinline.} =
|
||||
# 'noinline' so that 'nimProfile' does not perform the stack allocation
|
||||
@@ -86,16 +87,7 @@ else:
|
||||
|
||||
proc nimProfile() =
|
||||
## This is invoked by the compiler in every loop and on every proc entry!
|
||||
if gTicker == 0:
|
||||
gTicker = -1
|
||||
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
|
||||
if not isNil(profilingRequestedHook) and profilingRequestedHook():
|
||||
callProfilerHook(profilerHook)
|
||||
|
||||
{.pop.}
|
||||
|
||||
Reference in New Issue
Block a user