Using the Call Graph window

The Call Graph window presents a graph of the functions called during the run. It uses lines of varying thickness to graphically depict where your program spends its time. Thicker lines correspond directly to larger amounts of time spent along a path.

The call graph helps you understand the calling structure of your program and the major call paths that contributed to the total time of the run. Using the call graph, you can quickly discover the sources of bottlenecks.

By default, Quantify expands the call paths of the top 20 functions that contribute most to the overall time of the program. The call graph begins at the .root. accumulator, which represents the total amount of time used by all the functions in the program. For more information about the .root. accumulator, read How Quantify records function time.

Understanding the layout of the call graph

In single-threaded applications, the call graph begins at the .root. function, with one or two branches emanating from it. One branch corresponds to the initialization sequence of the program before it reaches your program's main function. This branch also contains C++ static initialization and at_exit processing, if any.

The other branch starts at pure_sigtramp and is present only if your program handled any signals. Multi-threaded applications can have several additional branches emanating from the .root. function. For more information, read Collecting data in threaded programs.

Curved lines in the call graph often indicate the presence of recursive functions or cycles of function calls. For more information, read How Quantify handles recursive functions.

If a function is not a leaf function, a triangle indicates how many of each function's immediate descendants are shown in the call graph.

    None of the immediate descendants are shown.

    Some of the immediate descendants are shown.

    All of the immediate descendants are shown.

Using the pop-up menu

To display the pop-up menu, right-click any function in the call graph.

You can use the pop-up menu to:

Expanding and collapsing descendants

Use the pop-up menu to expand or collapse the subtrees of descendants for individual functions.

After expanding or collapsing subtrees, you can select View > Redo layout to remove any gaps that your changes create in the call graph.

Locating functions in the call graph

To locate a particular caller or descendant of the selected function, select Locate callers or Locate descendants from the pop-up menu.

Quantify sorts the descendants by their contribution to the function's accumulated time.

If the function you are trying to locate is not present in the call graph, Quantify displays the most expensive path from the function that is the current focus to the desired function.

If the function is not in the descendant subtree of the current focus (for example, if it is the caller of the current focus), Quantify attempts to find a common function whose descendant subtree contains both the current focus (and hence current selection) and the desired function. It automatically makes that function the new focus and then displays the most expensive path from the new focus to the desired function.

Changing the focus of the call graph

You can change the focus of the call graph to a different function.

To change the focus of the call graph to a new function, right-click the desired function and select Change focus > Focus on subtree from the pop-up menu.

The selected function becomes the basis for scaling and expanding operations. For example, you can select View > Scale factors > % of focus to see numeric data scaled for the current focus.

Functions with multiple callers

The subtree of the function you select as the new focus of the call graph might contain functions that are called from outside of the subtree. Consider, for example, the functions malloc and free. Both of these functions are called from many different functions in a typical C program.

If you select one of malloc's callers as the new focus, its other callers are excluded from the subtree. In this case, malloc's function+descendants time can exceed that of its individual callers. This is because malloc distributed the additional time to the callers that are excluded from the subtree. If you display malloc's function+descendants time as a percentage of the focus function's function+descendants time, this percentage will exceed 100 percent. Quantify reports the percentage as “100+%.”

Quantify warns you if the subtree of the new focus contains any functions that distribute time to functions outside of the subtree. Quantify displays a count of these functions in the status bar at the bottom of the call graph and places an asterisk (*) next to their names in the call graph.

Displaying additional data for functions

To display additional data for functions in the call graph, select View > Display data. Select None to display functions without any additional data.   

Quantify describes the data that is displayed for each function in the legend at the top of the call graph. To hide or show the legend, select View > Legend.

Changing line scale factors

To change the scale of the lines in the call graph, select View > Line scale factors.

You can select from three line scale factors:

Shortening function names

You can shorten function names in order to tighten up the display in the call graph. Select View > Function names.

You can shorten function names by eliminating the C++ class name, argument list, or operator prefix. You can also specify a custom truncation length. In cases where demangling the full C++ name is ambiguous, Quantify prints ??? in the function's argument list.

Saving the call graph

To save a PostScript version of the current call graph, select File > Save call graph as.