forked from luck/tmp_suning_uos_patched
perf scripts python: exported-sql-viewer.py: Add IPC information to the Branch reports
Enhance the "All branches" and "Selected branches" reports to display IPC information if it is available. Committer testing: So, testing this I noticed that it all starts with the left arrow in every line, that should mean there is some tree there, i.e. look at all those ▶ symbols: Reports -> All Branches: Time CPU Command PID TID Branch Type In Tx Insn Cnt Cyc Cnt IPC Branch ▶ 187836112195670 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4f110 +_start (ld-2.28.so) ▶ 187836112195987 7 simple-retpolin 23003 23003 trace end No 0 883 0 7f6f33d4f110 _start (ld-2.28.so) -> 0 unknown +(unknown) ▶ 187836112199189 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4f110 +_start (ld-2.28.so) ▶ 187836112199189 7 simple-retpolin 23003 23003 call No 0 0 0 7f6f33d4f113 _start+0x3 (ld-2.28.so) -> 7f6f33d4ff50 +_dl_start (ld-2.28.so) ▶ 187836112199544 7 simple-retpolin 23003 23003 trace end No 17 996 0.02 7f6f33d4ff73 _dl_start+0x23 (ld-2.28.so) -> 0 +unknown (unknown) ▶ 187836112200939 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4ff73 +_dl_start+0x23 (ld-2.28.so) ▶ 187836112201229 7 simple-retpolin 23003 23003 trace end No 1 816 0.00 7f6f33d4ff7a _dl_start+0x2a (ld-2.28.so) -> 0 +unknown (unknown) ▶ 187836112203500 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4ff7a +_dl_start+0x2a (ld-2.28.so) But if you click on it, that ▶ disappears and a new click doesn't make it reappear, looks buggy, minor oddity, reported to Adrian. Reports -> Selected Branches, then ask for branches in the ld-2.28.so DSO: Time CPU Command PID TID Branch Type In Tx Insn Cnt Cyc Cnt IPC Branch ▶ 187836112195987 7 simple-retpolin 23003 23003 trace end No 0 883 0 7f6f33d4f110 _start (ld-2.28.so) -> 0 unknown (unknown) ▶ 187836112199189 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4f110 _start (ld-2.28.so) ▶ 187836112199189 7 simple-retpolin 23003 23003 call No 0 0 0 7f6f33d4f113 _start+0x3 (ld-2.28.so) -> 7f6f33d4ff50 _dl_start (ld-2.28.so) ▶ 187836112199544 7 simple-retpolin 23003 23003 trace end No 17 996 0.02 7f6f33d4ff73 _dl_start+0x23 (ld-2.28.so) -> 0 unknown (unknown) ▶ 187836112200939 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4ff73 _dl_start+0x23 (ld-2.28.so) ▶ 187836112201229 7 simple-retpolin 23003 23003 trace end No 1 816 0.00 7f6f33d4ff7a _dl_start+0x2a (ld-2.28.so) -> 0 unknown (unknown) ▶ 187836112203500 7 simple-retpolin 23003 23003 trace begin No 0 0 0 0 unknown (unknown) -> 7f6f33d4ff7a _dl_start+0x2a (ld-2.28.so) ▶ 187836112203528 7 simple-retpolin 23003 23003 unconditional jump No 0 0 0 7f6f33d4ffe7 _dl_start+0x97 (ld-2.28.so) -> 7f6f33d5000b _dl_start+0xbb (ld-2.28.so) ▶ 187836112203528 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d5000f _dl_start+0xbf (ld-2.28.so) -> 7f6f33d4fffb _dl_start+0xab (ld-2.28.so) ▶ 187836112203528 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d5000f _dl_start+0xbf (ld-2.28.so) -> 7f6f33d4fffb _dl_start+0xab (ld-2.28.so) ▶ 187836112203539 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d50025 _dl_start+0xd5 (ld-2.28.so) -> 7f6f33d50210 _dl_start+0x2c0 (ld-2.28.so) ▶ 187836112203539 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d5021a _dl_start+0x2ca (ld-2.28.so) -> 7f6f33d50360 _dl_start+0x410 (ld-2.28.so) ▶ 187836112203539 7 simple-retpolin 23003 23003 unconditional jump No 0 0 0 7f6f33d50377 _dl_start+0x427 (ld-2.28.so) -> 7f6f33d4ffff _dl_start+0xaf (ld-2.28.so) ▶ 187836112203539 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d5000f _dl_start+0xbf (ld-2.28.so) -> 7f6f33d4fffb _dl_start+0xab (ld-2.28.so) ▶ 187836112203562 7 simple-retpolin 23003 23003 conditional jump No 0 0 0 7f6f33d5000f _dl_start+0xbf (ld-2.28.so) -> 7f6f33d4fffb _dl_start+0xab (ld-2.28.so) Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/20190520113728.14389-19-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
ec7f448e2b
commit
530e22fd5c
|
@ -1369,11 +1369,11 @@ class FetchMoreRecordsBar():
|
||||||
|
|
||||||
class BranchLevelTwoItem():
|
class BranchLevelTwoItem():
|
||||||
|
|
||||||
def __init__(self, row, text, parent_item):
|
def __init__(self, row, col, text, parent_item):
|
||||||
self.row = row
|
self.row = row
|
||||||
self.parent_item = parent_item
|
self.parent_item = parent_item
|
||||||
self.data = [""] * 8
|
self.data = [""] * (col + 1)
|
||||||
self.data[7] = text
|
self.data[col] = text
|
||||||
self.level = 2
|
self.level = 2
|
||||||
|
|
||||||
def getParentItem(self):
|
def getParentItem(self):
|
||||||
|
@ -1405,6 +1405,7 @@ class BranchLevelOneItem():
|
||||||
self.dbid = data[0]
|
self.dbid = data[0]
|
||||||
self.level = 1
|
self.level = 1
|
||||||
self.query_done = False
|
self.query_done = False
|
||||||
|
self.br_col = len(self.data) - 1
|
||||||
|
|
||||||
def getChildItem(self, row):
|
def getChildItem(self, row):
|
||||||
return self.child_items[row]
|
return self.child_items[row]
|
||||||
|
@ -1485,7 +1486,7 @@ class BranchLevelOneItem():
|
||||||
while k < 15:
|
while k < 15:
|
||||||
byte_str += " "
|
byte_str += " "
|
||||||
k += 1
|
k += 1
|
||||||
self.child_items.append(BranchLevelTwoItem(0, byte_str + " " + text, self))
|
self.child_items.append(BranchLevelTwoItem(0, self.br_col, byte_str + " " + text, self))
|
||||||
self.child_count += 1
|
self.child_count += 1
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
@ -1536,16 +1537,37 @@ class BranchRootItem():
|
||||||
def getData(self, column):
|
def getData(self, column):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
# Calculate instructions per cycle
|
||||||
|
|
||||||
|
def CalcIPC(cyc_cnt, insn_cnt):
|
||||||
|
if cyc_cnt and insn_cnt:
|
||||||
|
ipc = Decimal(float(insn_cnt) / cyc_cnt)
|
||||||
|
ipc = str(ipc.quantize(Decimal(".01"), rounding=ROUND_HALF_UP))
|
||||||
|
else:
|
||||||
|
ipc = "0"
|
||||||
|
return ipc
|
||||||
|
|
||||||
# Branch data preparation
|
# Branch data preparation
|
||||||
|
|
||||||
|
def BranchDataPrepBr(query, data):
|
||||||
|
data.append(tohex(query.value(8)).rjust(16) + " " + query.value(9) + offstr(query.value(10)) +
|
||||||
|
" (" + dsoname(query.value(11)) + ")" + " -> " +
|
||||||
|
tohex(query.value(12)) + " " + query.value(13) + offstr(query.value(14)) +
|
||||||
|
" (" + dsoname(query.value(15)) + ")")
|
||||||
|
|
||||||
|
def BranchDataPrepIPC(query, data):
|
||||||
|
insn_cnt = query.value(16)
|
||||||
|
cyc_cnt = query.value(17)
|
||||||
|
ipc = CalcIPC(cyc_cnt, insn_cnt)
|
||||||
|
data.append(insn_cnt)
|
||||||
|
data.append(cyc_cnt)
|
||||||
|
data.append(ipc)
|
||||||
|
|
||||||
def BranchDataPrep(query):
|
def BranchDataPrep(query):
|
||||||
data = []
|
data = []
|
||||||
for i in xrange(0, 8):
|
for i in xrange(0, 8):
|
||||||
data.append(query.value(i))
|
data.append(query.value(i))
|
||||||
data.append(tohex(query.value(8)).rjust(16) + " " + query.value(9) + offstr(query.value(10)) +
|
BranchDataPrepBr(query, data)
|
||||||
" (" + dsoname(query.value(11)) + ")" + " -> " +
|
|
||||||
tohex(query.value(12)) + " " + query.value(13) + offstr(query.value(14)) +
|
|
||||||
" (" + dsoname(query.value(15)) + ")")
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def BranchDataPrepWA(query):
|
def BranchDataPrepWA(query):
|
||||||
|
@ -1555,10 +1577,26 @@ def BranchDataPrepWA(query):
|
||||||
data.append("{:>19}".format(query.value(1)))
|
data.append("{:>19}".format(query.value(1)))
|
||||||
for i in xrange(2, 8):
|
for i in xrange(2, 8):
|
||||||
data.append(query.value(i))
|
data.append(query.value(i))
|
||||||
data.append(tohex(query.value(8)).rjust(16) + " " + query.value(9) + offstr(query.value(10)) +
|
BranchDataPrepBr(query, data)
|
||||||
" (" + dsoname(query.value(11)) + ")" + " -> " +
|
return data
|
||||||
tohex(query.value(12)) + " " + query.value(13) + offstr(query.value(14)) +
|
|
||||||
" (" + dsoname(query.value(15)) + ")")
|
def BranchDataWithIPCPrep(query):
|
||||||
|
data = []
|
||||||
|
for i in xrange(0, 8):
|
||||||
|
data.append(query.value(i))
|
||||||
|
BranchDataPrepIPC(query, data)
|
||||||
|
BranchDataPrepBr(query, data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def BranchDataWithIPCPrepWA(query):
|
||||||
|
data = []
|
||||||
|
data.append(query.value(0))
|
||||||
|
# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string
|
||||||
|
data.append("{:>19}".format(query.value(1)))
|
||||||
|
for i in xrange(2, 8):
|
||||||
|
data.append(query.value(i))
|
||||||
|
BranchDataPrepIPC(query, data)
|
||||||
|
BranchDataPrepBr(query, data)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# Branch data model
|
# Branch data model
|
||||||
|
@ -1572,10 +1610,20 @@ class BranchModel(TreeModel):
|
||||||
self.event_id = event_id
|
self.event_id = event_id
|
||||||
self.more = True
|
self.more = True
|
||||||
self.populated = 0
|
self.populated = 0
|
||||||
|
self.have_ipc = IsSelectable(glb.db, "samples", columns = "insn_count, cyc_count")
|
||||||
|
if self.have_ipc:
|
||||||
|
select_ipc = ", insn_count, cyc_count"
|
||||||
|
prep_fn = BranchDataWithIPCPrep
|
||||||
|
prep_wa_fn = BranchDataWithIPCPrepWA
|
||||||
|
else:
|
||||||
|
select_ipc = ""
|
||||||
|
prep_fn = BranchDataPrep
|
||||||
|
prep_wa_fn = BranchDataPrepWA
|
||||||
sql = ("SELECT samples.id, time, cpu, comm, pid, tid, branch_types.name,"
|
sql = ("SELECT samples.id, time, cpu, comm, pid, tid, branch_types.name,"
|
||||||
" CASE WHEN in_tx = '0' THEN 'No' ELSE 'Yes' END,"
|
" CASE WHEN in_tx = '0' THEN 'No' ELSE 'Yes' END,"
|
||||||
" ip, symbols.name, sym_offset, dsos.short_name,"
|
" ip, symbols.name, sym_offset, dsos.short_name,"
|
||||||
" to_ip, to_symbols.name, to_sym_offset, to_dsos.short_name"
|
" to_ip, to_symbols.name, to_sym_offset, to_dsos.short_name"
|
||||||
|
+ select_ipc +
|
||||||
" FROM samples"
|
" FROM samples"
|
||||||
" INNER JOIN comms ON comm_id = comms.id"
|
" INNER JOIN comms ON comm_id = comms.id"
|
||||||
" INNER JOIN threads ON thread_id = threads.id"
|
" INNER JOIN threads ON thread_id = threads.id"
|
||||||
|
@ -1589,9 +1637,9 @@ class BranchModel(TreeModel):
|
||||||
" ORDER BY samples.id"
|
" ORDER BY samples.id"
|
||||||
" LIMIT " + str(glb_chunk_sz))
|
" LIMIT " + str(glb_chunk_sz))
|
||||||
if pyside_version_1 and sys.version_info[0] == 3:
|
if pyside_version_1 and sys.version_info[0] == 3:
|
||||||
prep = BranchDataPrepWA
|
prep = prep_fn
|
||||||
else:
|
else:
|
||||||
prep = BranchDataPrep
|
prep = prep_wa_fn
|
||||||
self.fetcher = SQLFetcher(glb, sql, prep, self.AddSample)
|
self.fetcher = SQLFetcher(glb, sql, prep, self.AddSample)
|
||||||
self.fetcher.done.connect(self.Update)
|
self.fetcher.done.connect(self.Update)
|
||||||
self.fetcher.Fetch(glb_chunk_sz)
|
self.fetcher.Fetch(glb_chunk_sz)
|
||||||
|
@ -1600,13 +1648,23 @@ class BranchModel(TreeModel):
|
||||||
return BranchRootItem()
|
return BranchRootItem()
|
||||||
|
|
||||||
def columnCount(self, parent=None):
|
def columnCount(self, parent=None):
|
||||||
|
if self.have_ipc:
|
||||||
|
return 11
|
||||||
|
else:
|
||||||
return 8
|
return 8
|
||||||
|
|
||||||
def columnHeader(self, column):
|
def columnHeader(self, column):
|
||||||
|
if self.have_ipc:
|
||||||
|
return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Insn Cnt", "Cyc Cnt", "IPC", "Branch")[column]
|
||||||
|
else:
|
||||||
return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Branch")[column]
|
return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Branch")[column]
|
||||||
|
|
||||||
def columnFont(self, column):
|
def columnFont(self, column):
|
||||||
if column != 7:
|
if self.have_ipc:
|
||||||
|
br_col = 10
|
||||||
|
else:
|
||||||
|
br_col = 7
|
||||||
|
if column != br_col:
|
||||||
return None
|
return None
|
||||||
return QFont("Monospace")
|
return QFont("Monospace")
|
||||||
|
|
||||||
|
@ -2114,10 +2172,10 @@ def GetEventList(db):
|
||||||
|
|
||||||
# Is a table selectable
|
# Is a table selectable
|
||||||
|
|
||||||
def IsSelectable(db, table, sql = ""):
|
def IsSelectable(db, table, sql = "", columns = "*"):
|
||||||
query = QSqlQuery(db)
|
query = QSqlQuery(db)
|
||||||
try:
|
try:
|
||||||
QueryExec(query, "SELECT * FROM " + table + " " + sql + " LIMIT 1")
|
QueryExec(query, "SELECT " + columns + " FROM " + table + " " + sql + " LIMIT 1")
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
@ -2854,6 +2912,12 @@ cd xed
|
||||||
sudo ./mfile.py --prefix=/usr/local install
|
sudo ./mfile.py --prefix=/usr/local install
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
</pre>
|
</pre>
|
||||||
|
<h3>Instructions per Cycle (IPC)</h3>
|
||||||
|
If available, IPC information is displayed in columns 'insn_cnt', 'cyc_cnt' and 'IPC'.
|
||||||
|
<p><b>Intel PT note:</b> The information applies to the blocks of code ending with, and including, that branch.
|
||||||
|
Due to the granularity of timing information, the number of cycles for some code blocks will not be known.
|
||||||
|
In that case, 'insn_cnt', 'cyc_cnt' and 'IPC' are zero, but when 'IPC' is displayed it covers the period
|
||||||
|
since the previous displayed 'IPC'.
|
||||||
<h3>Find</h3>
|
<h3>Find</h3>
|
||||||
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
|
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
|
||||||
Refer to Python documentation for the regular expression syntax.
|
Refer to Python documentation for the regular expression syntax.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user