VM profiler (#14833)

* Crude VM profiler

* Added --profileVM flag, refactoring

* fixed FileLine hash

* Use TLineInfo instead of own FileLine, updated formatting

* Refactoring, moved PStackFrame to vmdefs for cleaner data structure

* Moved vmprofiler to separate file

* Simplified TLineInfo hash, use toFileLineCol for output

* Hash

* Moved profile data into Config, dump only once at end of run

* Changed profile output header to show '#instr' instead of 'count'

* Do not accumulate instrcount for non-top frames

Co-authored-by: Ico Doornekamp <git@zevv.nl>
This commit is contained in:
Ico Doornekamp 2020-07-09 19:18:35 +02:00 • committed by GitHub
commit d7ccd82eac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 15 deletions

42
compiler/vmprofiler.nim Normal file
View file

@ -0,0 +1,42 @@
import
options, vmdef, times, lineinfos, strutils, tables,
msgs
proc enter*(prof: var Profiler, c: PCtx, tos: PStackFrame) {.inline.} =
if optProfileVM in c.config.globalOptions:
prof.tEnter = cpuTime()
prof.tos = tos
proc leave*(prof: var Profiler, c: PCtx) {.inline.} =
if optProfileVM in c.config.globalOptions:
let tLeave = cpuTime()
var tos = prof.tos
var data = c.config.vmProfileData.data
while tos != nil:
if tos.prc != nil:
let li = tos.prc.info
if li notin data:
data[li] = ProfileInfo()
data[li].time += tLeave - prof.tEnter
if tos == prof.tos:
inc data[li].count
tos = tos.next
proc dump*(conf: ConfigRef, pd: ProfileData): string =
var data = pd.data
echo "\nprof: µs #instr location"
for i in 0..<32:
var tMax: float
var infoMax: ProfileInfo
var flMax: TLineInfo
for fl, info in data:
if info.time > infoMax.time:
infoMax = info
flMax = fl
if infoMax.count == 0:
break
result.add " " & align($int(infoMax.time * 1e6), 10) &
align($int(infoMax.count), 10) & " " &
conf.toFileLineCol(flMax) & "\n"
data.del flMax