forked from github/verilator
Verilator_gantt: remove ASCII graphics
This commit is contained in:
parent
fd4595d6b4
commit
8ab51dbf22
1
Changes
1
Changes
@ -11,6 +11,7 @@ contributors that suggested a given feature are shown in []. Thanks!
|
||||
Verilator 4.213 devel
|
||||
==========================
|
||||
|
||||
* Verilator_gantt has removed the ASCII graphics, use the VCD output instead.
|
||||
* Verilator_gantt now shows the predicted mtask times, eval times, and additional statistics.
|
||||
* Verilator_gantt data files now include processor information, to allow later processing.
|
||||
* Fix verilator_profcfunc profile accounting (#3115).
|
||||
|
@ -158,8 +158,6 @@ def report():
|
||||
Global['measured_last_end'] = measured_last_end
|
||||
Global['predict_last_end'] = predict_last_end
|
||||
|
||||
report_graph()
|
||||
|
||||
# If we know cycle time in the same (rdtsc) units,
|
||||
# this will give us an actual utilization number,
|
||||
# (how effectively we keep the cores busy.)
|
||||
@ -293,108 +291,6 @@ def report_cpus():
|
||||
Global['cpu_socket_cores_warning'] = True
|
||||
|
||||
|
||||
def report_graph():
|
||||
time_per = Args.scale
|
||||
if time_per == 0:
|
||||
time_per = Global['measured_last_end'] / 40 # Start with 40 columns
|
||||
while time_per > 10:
|
||||
(graph, conflicts) = _make_graph(time_per)
|
||||
if not conflicts:
|
||||
break
|
||||
time_per = int(time_per / 2)
|
||||
# One more step so we can fit more labels
|
||||
time_per = int(time_per / 2)
|
||||
if time_per <= 0:
|
||||
time_per = 1
|
||||
|
||||
(graph, conflicts) = _make_graph(time_per)
|
||||
|
||||
print("\nThread gantt graph:")
|
||||
print(" Legend: One character width = %s rdtsc ticks" % time_per)
|
||||
print(" Legend: '&' = multiple mtasks in this period (character width)")
|
||||
|
||||
scale = " <-%d rdtsc total" % Global['measured_last_end']
|
||||
for col in range(len(scale),
|
||||
int(0.99 + (Global['measured_last_end'] / time_per))): # pylint: disable=unused-variable
|
||||
scale += "-"
|
||||
print(" " + scale + "->")
|
||||
|
||||
for thread in sorted(graph.keys()):
|
||||
print(" t: ", end="")
|
||||
_print_graph_line(graph[thread], '')
|
||||
|
||||
|
||||
def _make_graph(time_per):
|
||||
|
||||
# [thread][column] = char or #
|
||||
graph = collections.defaultdict(
|
||||
lambda: collections.defaultdict(lambda: ''))
|
||||
|
||||
conflicts = 0
|
||||
for thread in Threads:
|
||||
# Make potentially multiple characters per column
|
||||
multi_at_col = collections.defaultdict(lambda: '')
|
||||
for start in sorted(Threads[thread].keys()):
|
||||
end = Threads[thread][start]['end']
|
||||
# mtask = Threads[thread][start]['mtask']
|
||||
cpu = Threads[thread][start]['cpu']
|
||||
|
||||
startcol = _time_col(time_per, start)
|
||||
endcol = _time_col(time_per, end)
|
||||
|
||||
label = "["
|
||||
label += str(cpu) # Maybe make optional in future
|
||||
width = endcol - startcol + 1
|
||||
while len(label) < (width - 1): # -1 for ']'
|
||||
label += "-"
|
||||
label += "]"
|
||||
multi_at_col[startcol] += label
|
||||
|
||||
# Expand line to one char per column
|
||||
for col in multi_at_col:
|
||||
chars = multi_at_col[col]
|
||||
ok = True
|
||||
for coladd in range(0, len(chars)):
|
||||
if col + coladd in graph[thread]:
|
||||
ok = False
|
||||
break
|
||||
if not ok:
|
||||
if re.search(r'\[.*\[', chars): # Two begins or more
|
||||
conflicts += 1
|
||||
graph[thread][col] = "&"
|
||||
else:
|
||||
graph[thread][col] = "["
|
||||
for coladd in range(1, len(chars)):
|
||||
if col + coladd in graph[thread]:
|
||||
break
|
||||
graph[thread][col + coladd] = 'x'
|
||||
else:
|
||||
coladd = 0
|
||||
for char in chars:
|
||||
graph[thread][col + coladd] = char
|
||||
coladd += 1
|
||||
|
||||
if Args.debug:
|
||||
print("# Conflicts %d" % conflicts)
|
||||
return (graph, conflicts)
|
||||
|
||||
|
||||
def _print_graph_line(graph_thread, sep):
|
||||
at = 0
|
||||
for col in sorted(graph_thread.keys()):
|
||||
while at < col:
|
||||
print(' ', end="")
|
||||
at += 1
|
||||
c = graph_thread[col]
|
||||
print(c + sep, end="")
|
||||
at += len(c)
|
||||
print()
|
||||
|
||||
|
||||
def _time_col(time_per, time):
|
||||
return int(time / time_per)
|
||||
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
@ -573,10 +469,6 @@ Version 2.0.
|
||||
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
|
||||
|
||||
parser.add_argument('--debug', action='store_true', help='enable debug')
|
||||
parser.add_argument('--scale',
|
||||
help='number of time units per character in graph',
|
||||
type=int,
|
||||
default=0)
|
||||
parser.add_argument('--no-vcd',
|
||||
help='disable creating vcd',
|
||||
action='store_true')
|
||||
|
@ -10,27 +10,19 @@ starts and ends, and showing when each thread is busy or idle.
|
||||
|
||||
For an overview of use of verilator_gantt, see :ref:`Profiling`.
|
||||
|
||||
Gantt Chart Contents
|
||||
--------------------
|
||||
Gantt Chart VCD
|
||||
---------------
|
||||
|
||||
The generated Gantt chart has time on the X-axis. Times shown are to the
|
||||
scale printed, i.e. a certain about of time for each character width. The
|
||||
Y-axis shows threads, each thread's execution is shown on one line. That
|
||||
line shows "[" at the position in time when it executes.
|
||||
|
||||
Following the "[" is the CPU number the task executed on, followed by zero
|
||||
or more "-" to make the width of the characters match the scaled execution
|
||||
time, followed by a "]". If the scale is too small, the CPU number and
|
||||
mtask number will not be printed. If the scale is very small, a "&"
|
||||
indicates multiple mtasks started at that time position.
|
||||
|
||||
Also creates a value change dump (VCD) format dump file which may be viewed
|
||||
in a waveform viewer (e.g. C<GTKWave>). See below.
|
||||
Verilated_gnatt creates a value change dump (VCD) format dump file which
|
||||
may be viewed in a waveform viewer (e.g. C<GTKWave>):
|
||||
|
||||
.. figure:: figures/fig_gantt_min.png
|
||||
|
||||
Example verilator_gantt output, as viewed with GTKWave.
|
||||
|
||||
The viewed waveform chart has time on the X-axis, with one unit for each
|
||||
time tick of the system's high-performance counter.
|
||||
|
||||
|
||||
Gantt Chart VCD Signals
|
||||
-----------------------
|
||||
@ -86,13 +78,6 @@ The filename to read data from, defaults to "profile_threads.dat".
|
||||
|
||||
Displays a help summary, the program version, and exits.
|
||||
|
||||
.. option:: --scale <n>
|
||||
|
||||
Sets the number of time units per character on the X-axis of the generated
|
||||
Gantt chart. (On x86, time units are rdtsc ticks.) Defaults to 0, which
|
||||
will automatically compute a reasonable scale where no two mtasks need to
|
||||
fit into same character width's worth of scaled time.
|
||||
|
||||
.. option:: --no-vcd
|
||||
|
||||
Disables creating a .vcd file.
|
||||
|
@ -5,13 +5,6 @@ Argument settings:
|
||||
+verilator+prof+threads+window+2
|
||||
--threads 2
|
||||
|
||||
Thread gantt graph:
|
||||
Legend: One character width = 136 rdtsc ticks
|
||||
Legend: '&' = multiple mtasks in this period (character width)
|
||||
<-21875 rdtsc total-------------------------------------------------------------------------------------------------------------------------------------------->
|
||||
t: [19] [19] [19] [19]
|
||||
t: [10-] [10-] [10----] [10-] [10---] [10-][10][10] [10][10]
|
||||
|
||||
Analysis:
|
||||
Total threads = 2
|
||||
Total mtasks = 7
|
||||
|
Loading…
Reference in New Issue
Block a user