Skip to content

Commit

Permalink
kram-profile - more archive support, ignore unsupported files
Browse files Browse the repository at this point in the history
Notes on archives which are tricky due to storage of relative paths.  These can confuse the List id mechanism which is based on URL.  Just make sure to store unique identifying folder when building archives.
Can now build a report based on selected file - this will look at archive or same parent folder.  This allows multiple archives to be loaded.
  • Loading branch information
alecazam committed Mar 17, 2024
1 parent e407855 commit 841736b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 33 deletions.
6 changes: 3 additions & 3 deletions kram-profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ TODO: (x are done)
* x Find start/end time of each json files.
* x Support gzip trace files
* x Add sort by range (useful for mem/build traces)
* x Add zip archive support, can drop archive of 1+ traces

* Add frame type for perf traces for vsync ticker (binary format prob has it)
* Add zip archive support, can drop archive of 1+ traces
* Tie in with the excellent ClangBuildAnalyzer tool
* Scale specific traces to a single duration. That way the next file comes in at that scale.
* Move away from Catapult json to own binary format. Can then translate to json or use the Perfetto SDK to convert to protobufs.
Expand Down Expand Up @@ -61,8 +61,8 @@ Cpu Profilers. See for more details
* spall

* Commercial
* Telemetry - httpd://www.radgametools.com/telemeetry.htm
* Superluminal -
* Telemetry - httpd://www.radgametools.com/telemetry.htm
* Superluminal - higher-rate sampling profiler
* Xcode Instruments - see Xcode
* AMD Code Analyst - see Xcode
* Intel Vtune -
Expand Down
27 changes: 13 additions & 14 deletions kram-profile/kram-profile/File.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ enum FileType {

class File: Identifiable, /*Hashable, */ Equatable, Comparable
{
// TODO: archive url relative to archive so not unqique if multiple archives dropped
// but currently all lookup is by url, and not url + archive. Just make sure to
// include unique dir when building archives. zip has max 512 char path.

var id: String { url.absoluteString }
var name: String { url.lastPathComponent }
let url: URL
Expand Down Expand Up @@ -82,7 +86,7 @@ class File: Identifiable, /*Hashable, */ Equatable, Comparable
}
}

// show some of dir file is in, TODO: 2 levels not enough
// show some of dir file is in, TODO: 2 levels not enough?
public static func buildShortDirectory(url: URL) -> String {
let count = url.pathComponents.count

Expand Down Expand Up @@ -135,27 +139,20 @@ class File: Identifiable, /*Hashable, */ Equatable, Comparable
}
}

// TODO: now that it's a class, can probably elimiante that lookuFile calls
func generateDuration(file: File) -> String {
// need for duration
let f = lookupFile(url: file.url)
if f.duration != 0.0 {
// TODO: may want to add s/mb based on file type
return String(format:"%0.3f", f.duration) // sec vis to ms for now
}
else {
return ""
}
if file.duration == 0.0 { return "" }

let unitText = file.fileType == .Memory ? "m" : "s"
return "\(double:file.duration, decimals:3)\(unitText)"
}

func generateNavigationTitle(_ sel: String?) -> String {
if sel == nil {
return ""
}
if sel == nil { return "" }

let f = lookupFile(selection: sel!)
var text = generateDuration(file: f) + " " + f.name

// add the archive name
if let fileArchive = f.archive {
text += " in (" + fileArchive.name + ")"
}
Expand Down Expand Up @@ -407,6 +404,8 @@ func listFilesFromArchive(_ urlArchive: URL) -> [File] {
continue
}

// TODO: archives don't have full paths, so lookup can get confused
// if there are multiple archives with same paths.
let file = lookupFile(url:url)
if file.archive != archive {
file.archive = archive
Expand Down
55 changes: 39 additions & 16 deletions kram-profile/kram-profile/kram_profileApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -788,8 +788,25 @@ func updateFileBuildTimings(_ events: [CatapultEvent]) -> [String:BuildTiming] {
return buildTimings
}

func findFilesForBuildTimings(files: [File], selection: String) -> [File] {
let selectedFile = lookupFile(url:URL(string:selection)!)
let isArchive = selectedFile.archive != nil

let filteredFiles = files.filter { file in
if isArchive {
return file.archive != nil && file.archive! == selectedFile.archive!
}
else {
return file.parentFolders == selectedFile.parentFolders
}
}

return filteredFiles;
}

func postBuildTimingsReport(files: [File]) -> String? {
let buildTimings = mergeFileBuildTimings(files: files)
if buildTimings.isEmpty { return nil }
let buildJsonBase64 = buildPerfettoJsonFromBuildTimings(buildTimings: buildTimings)
let buildJS = postLoadFileJS(fileContentBase64: buildJsonBase64, title: "BuildTimings")
return buildJS
Expand Down Expand Up @@ -1413,8 +1430,6 @@ func loadFileJS(_ path: String) -> String? {

// Clang has some build totals as durations on fake threads
// but those are smaller than the full duration.
let doCompress = true

var json : Data

if file.containerType == .Compressed {
Expand All @@ -1436,6 +1451,10 @@ func loadFileJS(_ path: String) -> String? {
let decoder = JSONDecoder()
var catapultProfile = try decoder.decode(CatapultProfile.self, from: json)

if catapultProfile.traceEvents == nil {
return nil
}

// demangle the OptFunction name
for i in 0..<catapultProfile.traceEvents!.count {
let event = catapultProfile.traceEvents![i]
Expand Down Expand Up @@ -1481,13 +1500,8 @@ func loadFileJS(_ path: String) -> String? {
let fileContentFixed = try encoder.encode(catapultProfile)

// gzip compress the data before sending it over
if doCompress {
guard let compressedData = fileContentFixed.gzip() else { return nil }
fileContentBase64 = compressedData.base64EncodedString()
}
else {
fileContentBase64 = fileContentFixed.base64EncodedString()
}
guard let compressedData = fileContentFixed.gzip() else { return nil }
fileContentBase64 = compressedData.base64EncodedString()
}

return postLoadFileJS(fileContentBase64: fileContentBase64, title:fileURL.lastPathComponent)
Expand Down Expand Up @@ -1685,7 +1699,7 @@ struct kram_profileApp: App {
// preserve the original selection if still present
if selection != nil {
var found = false
for file in fileSearcher.files {
for file in fileSearcher.filesSorted {
if file.id == selection {
found = true
break;
Expand All @@ -1694,12 +1708,12 @@ struct kram_profileApp: App {

// load first file in the list
if !found {
selection = fileSearcher.files[0].id
selection = fileSearcher.filesSorted[0].id
}
}
else {
// load first file in the list
selection = fileSearcher.files[0].id
selection = fileSearcher.filesSorted[0].id
}
}
}
Expand Down Expand Up @@ -2097,16 +2111,25 @@ A tool to help profile mem, perf, and builds.

CommandGroup(after: .toolbar) {
// TODO: only enable if build files are present
// eventually don't run this on all, maybe find those related to selection
Button("Build Report") {
// should this be on all or just those seached?
let buildJS = postBuildTimingsReport(files: fileSearcher.filesSearched)
Button("Build Report All") {
let buildFiles = fileSearcher.files
let buildJS = postBuildTimingsReport(files: buildFiles)
if buildJS != nil {
runJavascript(myWebView, buildJS!)
}
}
.disabled(selection == nil)

Button("Build Report Selected") {
let buildFiles = findFilesForBuildTimings(files: fileSearcher.files, selection: selection!)
let buildJS = postBuildTimingsReport(files: buildFiles)
if buildJS != nil {
runJavascript(myWebView, buildJS!)
}
}
.disabled(selection == nil)


// must call through NSWindow
Button("See Below") {
// Window isn't set in AppDelegate, so menu item is skipped.
Expand Down

0 comments on commit 841736b

Please sign in to comment.