added load/percentile values for cycles/call profiling

This commit is contained in:
JetSetIlly 2024-03-28 06:52:31 +00:00
parent f098a31f1c
commit 1a26231b5e
4 changed files with 85 additions and 10 deletions

View file

@ -26,11 +26,18 @@ func (src *Source) NewFrame(rewinding bool) {
// calling newFrame() profiling data in a specific order
src.Cycles.NewFrame(nil, nil, rewinding)
var totalCyclesPerCall float32
for _, fn := range src.Functions {
fn.Cycles.NewFrame(&src.Cycles, nil, rewinding)
fn.CumulativeCycles.NewFrame(&src.Cycles, nil, rewinding)
fn.NumCalls.NewFrame(rewinding)
fn.CyclesPerCall.NewFrame(rewinding)
totalCyclesPerCall += fn.CyclesPerCall.Overall.FrameCount
}
for _, fn := range src.Functions {
fn.CyclesPerCall.PostNewFrame(totalCyclesPerCall, rewinding)
}
// traverse the SortedLines list and update the FrameCyles values

View file

@ -237,6 +237,7 @@ func (e SortedFunctions) Less(i int, j int) bool {
return (e.Functions[i].DeclLine.File.Filename <= e.Functions[j].DeclLine.File.Filename) != e.descending
case SortFunctionsName:
return (strings.ToUpper(e.Functions[i].Name) <= strings.ToUpper(e.Functions[j].Name)) != e.descending
case SortFunctionsFrameCycles:
if e.load {
return af.CyclesProgram.FrameLoad <= bf.CyclesProgram.FrameLoad != e.descending
@ -252,17 +253,28 @@ func (e SortedFunctions) Less(i int, j int) bool {
return af.CyclesProgram.MaxLoad <= bf.CyclesProgram.MaxLoad != e.descending
}
return af.CyclesProgram.MaxCount <= bf.CyclesProgram.MaxCount != e.descending
case SortFunctionsFrameCalls:
return afc.FrameCount <= bfc.FrameCount != e.descending
case SortFunctionsAverageCalls:
return afc.AverageCount <= bfc.AverageCount != e.descending
case SortFunctionsMaxCalls:
return afc.MaxCount <= bfc.MaxCount != e.descending
case SortFunctionsFrameCyclesPerCall:
if e.load {
return afp.FrameLoad <= bfp.FrameLoad != e.descending
}
return afp.FrameCount <= bfp.FrameCount != e.descending
case SortFunctionsAverageCyclesPerCall:
if e.load {
return afp.AverageLoad <= bfp.AverageLoad != e.descending
}
return afp.AverageCount <= bfp.AverageCount != e.descending
case SortFunctionsMaxCyclesPerCall:
if e.load {
return afp.MaxLoad <= bfp.MaxLoad != e.descending
}
return afp.MaxCount <= bfp.MaxCount != e.descending
}

View file

@ -96,11 +96,28 @@ func (cl *CyclesPerCall) NewFrame(rewinding bool) {
cl.Overscan.newFrame(rewinding)
}
// PostNewFrame is called after NewFrame() has been called for all instances of
// CyclesPerCall (ie. for all functions)
//
// This is because a total cycles/call value is needed to calculate the load
// values. If there's a simpler mathematical method of doing this then I'd
// prefer to do that
func (cl *CyclesPerCall) PostNewFrame(allFunctions float32, rewinding bool) {
cl.Overall.postNewFrame(allFunctions, rewinding)
cl.VBLANK.postNewFrame(allFunctions, rewinding)
cl.Screen.postNewFrame(allFunctions, rewinding)
cl.Overscan.postNewFrame(allFunctions, rewinding)
}
type CyclesPerCallScope struct {
FrameCount float32
AverageCount float32
MaxCount float32
FrameLoad float32
AverageLoad float32
MaxLoad float32
// whether the corresponding values are valid
FrameValid bool
AverageValid bool
@ -116,6 +133,10 @@ type CyclesPerCallScope struct {
// cycle and call count over all frames
totalCycles float32
totalCalls float32
// sum of cycle-per-call counts over all frames and for all functions
totalAverageCount float32
totalAllFunctions float32
}
func (cl *CyclesPerCallScope) call() {
@ -136,6 +157,9 @@ func (cl *CyclesPerCallScope) reset() {
cl.FrameCount = 0.0
cl.AverageCount = 0.0
cl.MaxCount = 0.0
cl.FrameLoad = 0.0
cl.AverageLoad = 0.0
cl.MaxLoad = 0.0
cl.FrameValid = false
cl.AverageValid = false
cl.MaxValid = false
@ -144,6 +168,7 @@ func (cl *CyclesPerCallScope) reset() {
cl.numFrames = 0.0
cl.totalCycles = 0.0
cl.totalCalls = 0.0
cl.totalAllFunctions = 0.0
}
func (cl *CyclesPerCallScope) newFrame(rewinding bool) {
@ -178,3 +203,25 @@ func (cl *CyclesPerCallScope) newFrame(rewinding bool) {
cl.cycles = 0.0
cl.calls = 0.0
}
func (cl *CyclesPerCallScope) postNewFrame(allFunctions float32, rewinding bool) {
if !rewinding {
cl.totalAverageCount += cl.AverageCount
cl.totalAllFunctions += allFunctions
}
if cl.FrameValid {
cl.FrameLoad = cl.FrameCount / allFunctions * 100
cl.AverageLoad = cl.totalAverageCount / cl.totalAllFunctions * 100
} else {
cl.FrameLoad = 0.0
}
if !cl.AverageValid {
cl.AverageLoad = 0.0
}
if cl.FrameLoad > cl.MaxLoad {
cl.MaxLoad = cl.FrameLoad
}
}

View file

@ -287,15 +287,12 @@ func (win *winCoProcProfiling) draw(coproc coprocessor.CartCoProc) {
imgui.Checkbox("Hide Unexecuted Items", &win.hideUnusedEntries)
drawDisabled(win.cyclesPerCall && win.tabSelected == functionTab, func() {
if win.tabSelected == functionTab {
imgui.SameLineV(0, 15)
if imgui.Checkbox("Percentile Figures", &win.percentileFigures) {
win.windowSortSpecDirty = true
}
})
if win.tabSelected == functionTab {
drawDisabled(win.cyclesPerCall, func() {
imgui.SameLineV(0, 15)
if imgui.Checkbox("Cumulative Figures", &win.cumulative) {
@ -472,7 +469,7 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
case 3:
if win.cyclesPerCall {
src.SortedFunctions.Sort(dwarf.SortFunctionsFrameCyclesPerCall, false,
false, s.SortDirection != imgui.SortDirectionAscending, win.focus)
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
} else {
src.SortedFunctions.Sort(dwarf.SortFunctionsFrameCycles, win.cumulative,
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
@ -480,7 +477,7 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
case 4:
if win.cyclesPerCall {
src.SortedFunctions.Sort(dwarf.SortFunctionsAverageCyclesPerCall, false,
false, s.SortDirection != imgui.SortDirectionAscending, win.focus)
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
} else {
src.SortedFunctions.Sort(dwarf.SortFunctionsAverageCycles, win.cumulative,
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
@ -488,7 +485,7 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
case 5:
if win.cyclesPerCall {
src.SortedFunctions.Sort(dwarf.SortFunctionsMaxCyclesPerCall, false,
false, s.SortDirection != imgui.SortDirectionAscending, win.focus)
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
} else {
src.SortedFunctions.Sort(dwarf.SortFunctionsMaxCycles, win.cumulative,
win.percentileFigures, s.SortDirection != imgui.SortDirectionAscending, win.focus)
@ -609,7 +606,11 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
imgui.PushStyleColor(imgui.StyleColorText, win.img.cols.CoProcSourceLoad)
if win.cyclesPerCall {
if cyclesPerCall.FrameValid {
imgui.Text(fmt.Sprintf("%.0f", cyclesPerCall.FrameCount))
if win.percentileFigures {
imgui.Text(fmt.Sprintf("%.02f", cyclesPerCall.FrameLoad))
} else {
imgui.Text(fmt.Sprintf("%.0f", cyclesPerCall.FrameCount))
}
} else {
imgui.Text("-")
}
@ -630,7 +631,11 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
imgui.PushStyleColor(imgui.StyleColorText, win.img.cols.CoProcSourceAvgLoad)
if win.cyclesPerCall {
if cyclesPerCall.AverageValid {
imgui.Text(fmt.Sprintf("%0.0f", cyclesPerCall.AverageCount))
if win.percentileFigures {
imgui.Text(fmt.Sprintf("%0.02f", cyclesPerCall.AverageLoad))
} else {
imgui.Text(fmt.Sprintf("%0.0f", cyclesPerCall.AverageCount))
}
} else {
imgui.Text("-")
}
@ -651,7 +656,11 @@ func (win *winCoProcProfiling) drawFunctions(src *dwarf.Source) {
imgui.PushStyleColor(imgui.StyleColorText, win.img.cols.CoProcSourceMaxLoad)
if win.cyclesPerCall {
if cyclesPerCall.MaxValid {
imgui.Text(fmt.Sprintf("%.0f", cyclesPerCall.MaxCount))
if win.percentileFigures {
imgui.Text(fmt.Sprintf("%.02f", cyclesPerCall.MaxLoad))
} else {
imgui.Text(fmt.Sprintf("%.0f", cyclesPerCall.MaxCount))
}
} else {
imgui.Text("-")
}