Application Profiler is a QNX tool that allows you to view the profiling results
generated by instrumented binaries that run on a QNX Neutrino target.
The results tell you who called each function as well as how often, how long was spent in
each function, and how much CPU time individual lines of codes used. This helps you locate
inefficient areas in your code without following its execution line by line.
How Application Profiler results are presented
When you launch an application with the Application Profiler enabled, the IDE
switches to the QNX
Analysis perspective and opens the Execution Time
view, which shows the application's execution time by function. The IDE also
creates a session for storing the profiling results, and displays this new session
in the Analysis Sessions view.
This view displays all sessions from analysis tools run on a project within the
current workspace. Each session has a header containing the tool icon, binary name,
session number, and launch time. Sessions from the Application Profiler,
Code Coverage,
Memory Analysis, and all
Valgrind tools are listed in this view, from the newest (at the top)
to the oldest (at the bottom). The session number gets incremented each time a
program is run with any of these tools.
For profiling sessions, the icon is a circle with a small clock and checkmark
().
Double-clicking the header opens the session (if it's not open)
and displays function information from all components in the
Execution Time view. To filter the results, expand the
header and click the appropriate component. For example, to display results for
functions in your program code but not in any libraries that it uses, click the
application binary.
When you select an active profiling session, which means the application is still
running, the view toolbar provides
Resume Profiling () and
Pause Profiling () controls that let you
start and stop profiling. You can specify signals to act as start and stop hooks
for these controls, through the
Control panel.
The Take Snapshot button () is also active, and it
allows you to capture the current data without stopping the profiling activity.
You can then compare the snapshot data with the final results or other snapshots.
This view displays the results of profiling sessions, using a table in which each
row provides statistics for one function. The table has these default columns:
- Name — The name of the function.
Deep Time — The time it took to execute the
function and all of its descendants. This metric is also referred to as
Total Function Time. It is the pure realtime interval from when the
function started until it ended, which includes its shallow time, the
sum of its children's deep times, and all time in which the thread
wasn't running while blocked inside of it. If the function was called
more than once, this column contains the sum of all runtimes when it
was called from a particular stack frame or parent function.
Inside each column entry, on the left, a green bar and percentage value
indicate the relative execution time. On the right, another value
indicates the absolute execution time.
For Sampling mode, this column isn't used.
Shallow Time — For Function Instrumentation
mode, this column is the deep time minus the sum of its children's
runtimes. It roughly represents the time spent in this function only.
However, it also includes the time for kernel and instrumented library
calls and for profiling the code.
For Sampling mode, it's an estimated time,
calculated by multiplying an interval time by the count of all samples
from this function.
The column entries have a green bar overlaid with a percentage value
(on the left) and another numeric value (on the right). These items
provide similar information as in the Deep Time
column.
- Count — The number of times the function was
called.
- Location — The location of the function in the
code.
To add or remove columns, click the View Menu dropdown (
) in the view
toolbar, then click
Preferences. You can add or remove any of
the following columns:
- Percent — The percentage of Deep Time compared
to the Total Time (or compared to the Root Node Time).
- Average — The average time spent in the
function.
- Max — The maximum time spent in the
function.
- Min — The minimum time spent in the
function.
- Time Stamp — A timestamp indicating the last
time the function was called, if present.
- Binary — The binary filename.
Note:
You can right-click in any row (i.e., function listing) and select context menu
options to display details about the function's call chains; for more information,
see
Call sequence information.
The
Execution Time toolbar provides actions including but not
limited to:
Annotated source
If your executable binary has debug information and your host has the source file for
a particular function, you can double-click its entry in the
Execution
Time view to open an annotated version of the code in the editor.
The editor shows solid green and graduated blue-yellow bars in the left margin.
CAUTION:
You may receive incorrect profiling data if you changed the source
since the last time you compiled. This is because the annotated editor relies on the
line information provided by the debug version of your binary.
The length of the bar represents the percentage of total execution time. The color
represents details specific to the function or single line, as follows:
- Blue-Yellow
- For the first line of a function, a blue-yellow bar shows its total
runtime. This includes the function's shallow time, the sum of its
children's deep times, and all time in which the thread wasn't running
while blocked inside of it.
- Green
- For a line of code, a green bar shows the amount of time for the inline
sampling or call-pair data. The lengths of the green bars within a
function add up to the length of the blue-yellow bar on its first line.
To view quantitative profiling data, hover the pointer over a colored bar. The
resulting tooltip shows the total number of milliseconds and total percentage of
execution time for that code. For children, the tooltip shows the percentage of time
relative to the parent.
You can right-click a table row (i.e., function listing) and then click context menu
options to see how the current function fits into the program's call sequence.
The options include but aren't limited to:
- Show Calls
- List all functions called by the selected function. The resulting list lets
you examine specific call chains to find which ones have the greatest
performance impact. You can expand the entries of descendant functions to
see how execution time is distributed among them.
- In the called functions list, the columns that are shown by default or that
can be selected through the Preferences dropdown
option are the same as those for the original profiling results.
Also, you can right-click again and choose this same option or
Show Reverse Calls (if it's available), to navigate
up or down a particular call stack.
Note: For this and other options, you can use the
Go Back
(
) and
Go Forward
(
) toolbar buttons to move
between the menu action results and original profiling results.
- Show Reverse Calls
- List all callers of the selected function. The resulting list shows the
execution times for all calling functions. The same columns are shown, and
you can right-click again and choose this same option or
Show Calls, to navigate up or down a particular call
stack.
- You can show the reverse calls only for functions compiled with profiling
instrumentation.
- Show Call Graph
Display a graph of how the functions are called within the program.
- This graph represents functions with colored boxes.
The selected function appears in the middle, in blue. On the left, in
orange, are all functions that called this function. On the right, in lighter
orange, are all functions that the selected function called.
- To see the calls to and from a function, click its box in the call graph.
If you hover the pointer over this box, Deep Time,
Percent, and Count information
is displayed, if the information is available.
- You can show the call graphs only for functions compiled with profiling
instrumentation.
You can compare the results of two
profiling sessions to see the effect of changes you made to an application.
The comparison feature calculates and displays the differences in function runtimes
and other metrics between the sessions, in the Execution Time
view.
In the comparison results, the columns show the profiling measurement changes from
the older to the newer session (i.e., the new values minus the old ones).
If a function ran in only one session, its values from that session are displayed.
To hide insignificant results (e.g., <1% difference) or apply other filters,
click the View Menu dropdown
(
), then click
Filters. The IDE opens a window with several fields for
filtering the profiling results:
You can obtain more information from the tooltips. If you hover the pointer in a
Deep Time or
Shallow Time
column, the IDE displays a popup message with the old and new time values
as well as their absolute and relative differences: