If you have not already done so, you must collect performance data for synprog. See Collecting Data for the synprog Example for instructions. Once you have collected performance data, you must open the experiment test.1.er.
This part of the example demonstrates how the Performance Analyzer assigns metrics to functions in a recursive sequence. In the data collected by the Sampling Collector, each instance of a function call is recorded, but in the analysis, the metrics for all instances of a given function are aggregated. The synprog program contains two examples of recursive calling sequences:
-
Function recurse() demonstrates direct recursion. It calls function real_recurse(), which then calls itself until a test condition is met. At that point it performs some work that requires user CPU time The flow of control returns through successive calls to real_recurse() until it reaches recurse().
-
Function bounce() demonstrates indirect recursion. It calls function bounce_a(), which checks to see if a test condition is met. If it is not, it calls function bounce_b(). bounce_b() in turn calls bounce_a(). This sequence continues until the test condition in bounce_a() is met. Then bounce_a() performs some work that requires user CPU time, and the flow of control returns through successive calls to bounce_b() and bounce_a() until it reaches bounce().
In either case, exclusive metrics belong only to the function in which the actual work is done, in these cases real_recurse() and bounce_a(). These metrics are passed up as inclusive metrics to every function that calls the final function.
-
In the Functions tab, find function recurse() and select it.
Instead of scrolling the function list you can use the Find tool.
Function recurse() has inclusive user CPU time, but its exclusive user CPU time is zero because all recurse() does is to call real_recurse().
Note: Because profiling experiments are statistical in nature, the experiment that you run on synprog might record one or two profile events in recurse(), and recurse() might show a small exclusive CPU time value. However, the exclusive time due to these events is much less than the inclusive time.
-
Click the Callers-Callees tab.
The selected function, recurse(), is shown in the center pane. The function real_recurse(), which is called by recurse(), is shown in the lower pane. This pane is termed the Callees pane.
-
Click real_recurse().
The Callers-Callees tab now displays information for real_recurse():
-
Both recurse() and real_recurse() appear in the Callers pane (the upper pane) as callers of real_recurse(), because after recurse() calls real_recurse(), real_recurse() calls itself recursively.
-
real_recurse() also appears in the Callees pane because it calls itself.
-
Exclusive metrics as well as inclusive metrics are displayed for real_recurse(), where the actual user CPU time is spent. The exclusive metrics are passed up to recurse() as inclusive metrics.
-
The callee attributed metrics are affected by the recursive nature of the call. In a non-recursive call sequence, a single callee would attribute all of its inclusive metrics to the caller. In this case, real_recurse() is a leaf function as well as a caller and a callee of itself. To avoid double-counting of attributed metrics, the callee instance shows no attributed time. The appearance of real_recurse() as a callee gives information about the call sequence, but not about the attributed time.
-
Likewise, the caller attributed metrics are affected by the recursive nature of the call. None of the inclusive time spent in real_recurse() is attributed to the caller recurse(), which is the ultimate caller of real_recurse(). Instead, the time is attributed to the caller of the instance of real_recurse() where the exclusive time is spent. To examine attributed metrics for recurse(), you should make it the selected function.
-
Find function bounce() in the Functions tab and select it.
Function bounce() shows inclusive user CPU time, but its exclusive user CPU time is zero. This is because all bounce() does is to call bounce_a().
-
Click the Callers-Callees tab.
The Callers-Callees tab shows that bounce() calls only one function, bounce_a().
-
Click bounce_a().
The Callers-Callees tab now displays information for bounce_a():
-
Both bounce() and bounce_b() appear in the Callers pane as callers of bounce_a().
-
In addition, bounce_b() appears in the Callees pane because it is called by bounce_a().
-
Exclusive as well as inclusive metrics are displayed for bounce_a(), where the actual user CPU time is spent. These are passed up to the functions that call bounce_a() as inclusive metrics.
-
All of the inclusive time in bounce_b() is attributed to calls to bounce_a(), but none of the inclusive time in bounce() is attributed to calls to bounce_a(). The inclusive time in bounce() and bounce_b() are not separate but are in fact the same time represented twice. To avoid double counting of attributed time, only the direct caller of the function where the time is spent shows the attributed time. This situation is the same as for recurse() and real_recurse().
-
Because bounce_a() is the leaf function as well as an intermediate function, bounce_b() as a callee does not attribute any time to bounce_a(), to avoid double-counting of attributed time.
-
Click bounce_b().
The Callers-Callees tab now displays information for bounce_b(). bounce_a() appears in both the Callers pane and the Callees pane. The callee attributed time is shown correctly , because bounce_b() is not a leaf function, and accumulates inclusive time from its call to the instance of bounce_a() in which the work is done.
Can't find what you are looking for?
Email docfeedback@sun.com with your comments.
Legal Notices