Skip to content

Commit

Permalink
Add profiling zones (I know..) and add some optimizations
Browse files Browse the repository at this point in the history
draw.updateGraphs is only called once per frame, if needed
not once per message.

frame path to node lookups are now cached.
  • Loading branch information
pfirsich committed Jun 6, 2018
1 parent c09ee07 commit 1fb190c
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 24 deletions.
30 changes: 21 additions & 9 deletions draw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ local function getNodeString(node)
end

local function renderSubGraph(node, x, y, width, graphFunc, center)
--print(node.name, x, y, width)

prof.push("renderSubGraph")
local border = 2
local font = lg.getFont()

Expand Down Expand Up @@ -161,7 +160,7 @@ local function renderSubGraph(node, x, y, width, graphFunc, center)
hovered = hovered or childHover
end
end

prof.pop("renderSubGraph")
return hovered
end

Expand All @@ -170,6 +169,7 @@ local function getFramePos(i)
end

local function buildGraph(graph, key, valueOffset, valueScale, mean, path)
prof.push("buildGraph")
local x, w = 0, lg.getWidth()
local y, h = draw.getGraphCoords()

Expand All @@ -191,11 +191,14 @@ local function buildGraph(graph, key, valueOffset, valueScale, mean, path)
graph[p*2-1+0] = x + (p - 1) / (numPoints - 1) * w
graph[p*2-1+1] = y + (1 - (mean.mean(accum, n) or 0)) * h
end
prof.pop("buildGraph")
end

function draw.updateGraphs()
prof.push("draw.updateGraphs")
buildGraph(graphs.time, "deltaTime", 0, frames.maxDeltaTime, util.mean[draw.graphMean], rootPath)
buildGraph(graphs.mem, "memoryEnd", 0, frames.maxMemUsage, util.mean[draw.graphMean], rootPath)
prof.pop("draw.updateGraphs")
end

function draw.getGraphCoords()
Expand Down Expand Up @@ -229,24 +232,24 @@ function draw.popRootPath(path)
end

function love.draw()
prof.push("love.draw")
local winW, winH = lg.getDimensions()

if #frames < 1 then
lg.setFont(fonts.mode)
lg.print("Waiting for frames..", 5, 5)

prof.pop("love.draw")
prof.pop("frame")
prof.enabled(false)
return
end

local mean = util.mean[draw.graphMean]

-- render frame overview at the bottom
local spacing = 1
if winW / #frames < 3 then
spacing = 0
end
local width = (winW - spacing) / #frames - spacing
prof.push("heatmap")
local vMargin = 5

local numLines = math.min(#frames, winW)
local lineWidth = winW / numLines
local frameIndex = 1
Expand All @@ -269,9 +272,11 @@ function love.draw()
lg.setColor(c, c, c)
lg.rectangle("fill", x, y, lineWidth, const.frameOverviewHeight - vMargin*2)
end
prof.pop("heatmap")

local graphY, graphHeight = draw.getGraphCoords()

-- draw current frame/selection
if frames.current.index then
lg.setColor(const.frameCursorColor)
local x = getFramePos(frames.current.index)
Expand Down Expand Up @@ -302,6 +307,7 @@ function love.draw()
infoLine = ("frame %d: %.4f ms, %.3f KB"):format(frame, duration, memory)
end

-- draw ticks
local totalDur = frames[#frames].endTime - frames[1].startTime
local tickInterval = 10
local numTicks = math.floor(totalDur / tickInterval)
Expand Down Expand Up @@ -340,6 +346,7 @@ function love.draw()
lg.print(("memory usage (max: %d KB)"):format(frames.maxMemUsage), 5, graphY)

-- render flame graph for current frame
prof.push("flame graph")
lg.setFont(fonts.mode)
lg.print("graph type: " .. draw.flameGraphType, 5, 5)
lg.setFont(fonts.node)
Expand All @@ -362,6 +369,7 @@ function love.draw()
infoLine = ("This frame does not have a node with path '%s'"):format(
util.nodePathToStr(rootPath))
end
prof.pop("flame graph")

if infoLine then
lg.print(infoLine, 5, graphY - const.infoLineHeight + 5)
Expand All @@ -383,6 +391,10 @@ function love.draw()
lg.setColor(1, 1, 1)
lg.printf(helpText, 20, 20, winW - 40)
end

prof.pop("love.draw")
prof.pop("frame")
prof.enabled(false)
end

return draw
20 changes: 14 additions & 6 deletions frames.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ local function getNodeCount(node)
return counter
end

local function buildGraph(data)
local function buildNodeGraph(data)
prof.push("buildNodeGraph")
local frames = {}
local nodeStack = {}
for _, event in ipairs(data) do
Expand All @@ -47,7 +48,7 @@ local function buildGraph(data)
error("Profiling data malformed: Pushed a new frame when the last one was not popped yet!")
end

node.index = #frames + 1
node.pathCache = {}
table.insert(frames, node)
else
if not top then
Expand All @@ -70,6 +71,7 @@ local function buildGraph(data)
table.remove(nodeStack)
end
end
prof.pop("buildNodeGraph")
return frames
end

Expand Down Expand Up @@ -108,22 +110,28 @@ local deltaTimes = {}
local memUsages = {}

local function updateRanges(newFrames)
prof.push("updateRanges")
frames.minDeltaTime, frames.maxDeltaTime =
updateRange(newFrames, deltaTimes, "deltaTime", 0.005, 5)
frames.minMemUsage, frames.maxMemUsage =
updateRange(newFrames, memUsages, "memoryEnd")
prof.pop("updateRanges")
end

function frames.addFrames(data)
local newFrames = buildGraph(data)
prof.push("frames.addFrames")
local newFrames = buildNodeGraph(data)

prof.push("extend list")
for i, frame in ipairs(newFrames) do
table.insert(frames, frame)
frame.index = #frames
end
if frames.current == nil then
frames.current = frames[1]
end
frames.current = frames.current or frames[1]
prof.pop("extend list")

updateRanges(newFrames)
prof.pop("frames.addFrames")
end

return frames
48 changes: 39 additions & 9 deletions main.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
local lg = love.graphics
local msgpack = require "MessagePack"

PROF_CAPTURE = false
prof = require("jprof")
prof.enabled(false)

local draw = require("draw")
local getFrameAverage = require("frameAverage")
local util = require("util")
Expand Down Expand Up @@ -82,7 +86,28 @@ function love.resize()
draw.updateGraphs()
end

function love.quit()
prof.write("prof.mpack")
end

local function peekHeader(msgBuffer)
local a, b, c, d = msgBuffer:byte(1, 4)
return d + 0x100 * (c + 0x100 * (b + 0x100 * a))
end

local function processMessage(msgBuffer, msgLen)
prof.push("processMessage")
local headerLen = 4
local msg = msgBuffer:sub(headerLen+1, headerLen+msgLen)
local data = msgpack.unpack(msg)
frames.addFrames(data)
prof.pop("processMessage")
end

function love.update()
prof.enabled(true)
prof.push("frame")
prof.push("love.update")
local x, y = love.mouse.getPosition()
if love.mouse.isDown(1) and y > select(1, draw.getGraphCoords()) then
local frameIndex = pickFrameIndex(x)
Expand All @@ -108,19 +133,24 @@ function love.update()
end
until netData == nil

prof.push("read messages")
local headerLen = 4
local updateGraphs = false
while netMsgBuffer:len() > headerLen do
local a, b, c, d = netMsgBuffer:byte(1, 4)
local len = d + 0x100 * (c + 0x100 * (b + 0x100 * a))

if netMsgBuffer:len() >= headerLen + len then
local msg = netMsgBuffer:sub(headerLen+1, headerLen+len)
netMsgBuffer = netMsgBuffer:sub(headerLen+len+1)
local data = msgpack.unpack(msg)
frames.addFrames(data)
draw.updateGraphs()
local msgLen = peekHeader(netMsgBuffer)

if netMsgBuffer:len() >= headerLen + msgLen then
processMessage(netMsgBuffer, msgLen)
netMsgBuffer = netMsgBuffer:sub(headerLen+msgLen+1)
updateGraphs = true
else
break
end
end
prof.pop("read messages")

if updateGraphs or love.keyboard.isDown("u") then
draw.updateGraphs()
end
prof.pop("love.update")
end
5 changes: 5 additions & 0 deletions util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ function util.nodePathToStr(nodePath)
end

function util.getNodeByPath(frame, path)
if frame.pathCache[path] then
return frame.pathCache[path]
end

local current = frame
for _, part in ipairs(path) do
local found = false
Expand All @@ -81,6 +85,7 @@ function util.getNodeByPath(frame, path)
return nil
end
end
frame.pathCache[path] = current
return current
end

Expand Down

0 comments on commit 1fb190c

Please sign in to comment.