|
|
#include <unistd.h>
void profil(unsigned short *buff,
unsigned int bufsiz,
unsigned int offset,
unsigned int scale);
The profil() function provides CPU-use statistics by profiling the amount of CPU time expended by a program. The profil() function generates the statistics by creating an execution histogram for a current process. The histogram is defined for a specific region of program code to be profiled, and the identified region is logically broken up into a set of equal size subdivisions, each of which corresponds to a count in the histogram. With each clock tick, the current subdivision is identified and its corresponding histogram count is incremented. These counts establish a relative measure of how much time is being spent in each code subdivision. The resulting histogram counts for a profiled region can be used to identify those functions that consume a disproportionately high percentage of CPU time.
buff is a buffer of bufsiz bytes in which the histogram counts are stored in an array of unsigned short int.
offset, scale, and bufsiz specify the region to be profiled.
offset is effectively the start address of the region to be profiled.
scale, broadly speaking, is a contraction factor that indicates how much smaller the histogram buffer is than the region to be profiled. More precisely, scale is interpreted as an unsigned 16-bit fixed-point fraction with the decimal point implied on the left. Its value is the reciprocal of the number of bytes in a subdivision, per byte of histogram buffer. Since there are two bytes per histogram counter, the effective ratio of subdivision bytes per counter is one half the scale.
Several observations can be made:
The values are used within the kernel as follows: when the process
is interrupted for a clock tick,
the value of
offset
is subtracted
from the current value of the program counter (pc), and the remainder
is multiplied by
scale
to derive a result.
That result is used as an index into the histogram
array to locate the cell to be incremented.
Therefore, the cell count represents the number of times that the process
was executing code in the subdivision associated with that cell when the
process was interrupted.
scale can be computed as (RATIO * 0200000L), where RATIO is the desired ratio of bufsiz to profiled region size, and has a value between 0 and 1. Qualitatively speaking, the closer RATIO is to 1, the higher the resolution of the profile information.
bufsiz can be computed as (size_of_region_to_be_profiled * RATIO).
Profiling is turned off by giving a scale of 0 or 1, and is rendered ineffective by giving a bufsiz of 0. Profiling is turned off when an exec.2 is executed, but remains on in both child and parent processes after a fork.2 Profiling is turned off if a buff update would cause a memory fault.
In Solaris releases prior to 2.6, calling profil() in a multi-threaded program would impact only the calling LWP; the profile state was not inherited at LWP creation time. To profile a multi-threaded program with a global profile buffer, each thread needed to issue a call to profil() at threads start-up time, and each thread had to be a bound thread. This was cumbersome and did not easily support dynamically turning profiling on and off. In Solaris 2.6, the profil() system call for multi-threaded processes has global impact -- that is, a call to profil() impacts all LWPs/threads in the process. This may cause applications that depend on the previous per-LWP semantic to break, but it is expected to improve multi-threaded programs that wish to turn profiling on and off dynamically at runtime.
|
|
Created by unroff & hp-tools. © by Hans-Peter Bischof. All Rights Reserved (1997).
Last modified 07/October/97