History

perf scripts python: export-to-sqlite.py: Export IPC information

Export cycle and instruction counts on samples and calls tables. Committer testing: First runs some workload collecting intel_pt with the 'cyc' ter just for userspace: [root@quaco adrian.hunter]# perf record -o simple-retpoline.perf.data -e intel_pt/cyc/u ./simple-retpoline [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.035 MB simple-retpoline.perf.data ] [root@quaco adrian.hunter]# Then use the export-to-sqlite.py script to see if the changes in this cset don't make it to break and if the changes in the db schema are the ones expected: [root@quaco adrian.hunter]# perf script -i simple-retpoline.perf.data --itrace=be -s ~acme/libexec/perf-core/scripts/python/export-to-sqlite.py simple-retpoline.db branches calls 2019-05-31 11:50:46.942710 Creating database ... 2019-05-31 11:50:46.949663 Writing records... 2019-05-31 11:50:47.224033 Adding indexes 2019-05-31 11:50:47.231599 Done [root@quaco adrian.hunter]# Now lets use the db: [root@quaco adrian.hunter]# sqlite3 simple-retpoline.db SQLite version 3.26.0 2018-12-01 12:34:55 Enter ".help" for usage hints. sqlite> .schema samples CREATE TABLE samples (id integer NOT NULL PRIMARY KEY,evsel_id bigint,machine_id bigint,thread_id bigint,comm_id bigint,dso_id bigint,symbol_id bigint,sym_offset bigint,ip bigint,time bigint,cpuinteger,to_dso_id bigint,to_symbol_id bigint,to_sym_offset bigint,to_ip bigint,branch_type integer,in_tx boolean,call_path_id bigint,insn_count bigint,cyc_count bigint); sqlite> Cool, the 'insn_count' and 'cyc_count' are there, now lets see if we can use them in a query: sqlite> select insn_count,cyc_count from samples where cyc_count > 1500 and insn_count < 10; 6|1507 sqlite> select insn_count,cyc_count from samples where cyc_count > 1500; 118|2210 140|1516 3783|1861 132|1521 6|1507 sqlite> Seems to work :-)

Adrian Hunter committed 7 years ago

Commit 64adadb1 parent 52a2ab61 file · +24 −12Browse files

Showing the changes to tools/perf/scripts/python (1 of 1 file). Show all

Unified · Split

tools/perf/scripts/python/export-to-sqlite.py+24−12
@@ -218,7 +218,9 @@ if branches: · 217 unmodified lines
218 'to_ip bigint,'218 'to_ip bigint,'
219 'branch_type integer,'219 'branch_type integer,'
220 'in_tx boolean,'220 'in_tx boolean,'
221 'call_path_id bigint)')221 'call_path_id bigint,'
222 'insn_count bigint,'
223 'cyc_count bigint)')
222else:224else:
223 do_query(query, 'CREATE TABLE samples ('225 do_query(query, 'CREATE TABLE samples ('
224 'id integer NOT NULL PRIMARY KEY,'226 'id integer NOT NULL PRIMARY KEY,'
@@ -242,7 +244,9 @@ else: · 17 unmodified lines
242 'data_src bigint,'244 'data_src bigint,'
243 'branch_type integer,'245 'branch_type integer,'
244 'in_tx boolean,'246 'in_tx boolean,'
245 'call_path_id bigint)')247 'call_path_id bigint,'
248 'insn_count bigint,'
249 'cyc_count bigint)')
246 250
247if perf_db_export_calls or perf_db_export_callchains:251if perf_db_export_calls or perf_db_export_callchains:
248 do_query(query, 'CREATE TABLE call_paths ('252 do_query(query, 'CREATE TABLE call_paths ('
@@ -263,7 +267,9 @@ if perf_db_export_calls: · 14 unmodified lines
263 'return_id bigint,'267 'return_id bigint,'
264 'parent_call_path_id bigint,'268 'parent_call_path_id bigint,'
265 'flags integer,'269 'flags integer,'
266 'parent_id bigint)')270 'parent_id bigint,'
271 'insn_count bigint,'
272 'cyc_count bigint)')
267 273
268# printf was added to sqlite in version 3.8.3274# printf was added to sqlite in version 3.8.3
269sqlite_has_printf = False275sqlite_has_printf = False
@@ -359,6 +365,9 @@ if perf_db_export_calls: · 89 unmodified lines
359 'return_time,'365 'return_time,'
360 'return_time - call_time AS elapsed_time,'366 'return_time - call_time AS elapsed_time,'
361 'branch_count,'367 'branch_count,'
368 'insn_count,'
369 'cyc_count,'
370 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
362 'call_id,'371 'call_id,'
363 'return_id,'372 'return_id,'
364 'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'373 'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'
@@ -384,7 +393,10 @@ do_query(query, 'CREATE VIEW samples_view AS ' · 19 unmodified lines
384 'to_sym_offset,'393 'to_sym_offset,'
385 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'394 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'
386 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'395 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'
387 'in_tx'396 'in_tx,'
397 'insn_count,'
398 'cyc_count,'
399 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC'
388 ' FROM samples')400 ' FROM samples')
389 401
390do_query(query, 'END TRANSACTION')402do_query(query, 'END TRANSACTION')
@@ -407,15 +419,15 @@ branch_type_query = QSqlQuery(db) · 16 unmodified lines
407branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")419branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")
408sample_query = QSqlQuery(db)420sample_query = QSqlQuery(db)
409if branches:421if branches:
410 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")422 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
411else:423else:
412 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")424 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
413if perf_db_export_calls or perf_db_export_callchains:425if perf_db_export_calls or perf_db_export_callchains:
414 call_path_query = QSqlQuery(db)426 call_path_query = QSqlQuery(db)
415 call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")427 call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")
416if perf_db_export_calls:428if perf_db_export_calls:
417 call_query = QSqlQuery(db)429 call_query = QSqlQuery(db)
418 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")430 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
419 431
420def trace_begin():432def trace_begin():
421 printdate("Writing records...")433 printdate("Writing records...")
@@ -427,10 +439,10 @@ def trace_begin(): · 5 unmodified lines
427 comm_table(0, "unknown")439 comm_table(0, "unknown")
428 dso_table(0, 0, "unknown", "unknown", "")440 dso_table(0, 0, "unknown", "unknown", "")
429 symbol_table(0, 0, 0, 0, 0, "unknown")441 symbol_table(0, 0, 0, 0, 0, "unknown")
430 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)442 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
431 if perf_db_export_calls or perf_db_export_callchains:443 if perf_db_export_calls or perf_db_export_callchains:
432 call_path_table(0, 0, 0, 0)444 call_path_table(0, 0, 0, 0)
433 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)445 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
434 446
435unhandled_count = 0447unhandled_count = 0
436 448
@@ -486,14 +498,14 @@ def sample_table(*x): · 49 unmodified lines
486 if branches:498 if branches:
487 for xx in x[0:15]:499 for xx in x[0:15]:
488 sample_query.addBindValue(str(xx))500 sample_query.addBindValue(str(xx))
489 for xx in x[19:22]:501 for xx in x[19:24]:
490 sample_query.addBindValue(str(xx))502 sample_query.addBindValue(str(xx))
491 do_query_(sample_query)503 do_query_(sample_query)
492 else:504 else:
493 bind_exec(sample_query, 22, x)505 bind_exec(sample_query, 24, x)
494 506
495def call_path_table(*x):507def call_path_table(*x):
496 bind_exec(call_path_query, 4, x)508 bind_exec(call_path_query, 4, x)
497 509
498def call_return_table(*x):510def call_return_table(*x):
499 bind_exec(call_query, 12, x)511 bind_exec(call_query, 14, x)