Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ pfm(7) — OSF/1 3.0 αXP

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

kprofile(1)

uprofile(1)

prof(1)

pfm(7)  —  Special Files

NAME

pfm − The 21064 performance counter pseudo-device

SYNOPSIS

pseudo-device pfm

DESCRIPTION

The pfm pseudo-device is the interface to the 21064 on-chip performance counters.  The 21064 has two counters each of which can be independently programmed to count certain internal or external events.  Each counter interrupts the O/S when a certain number of the selected events have been counted.  There are three actions that can happen at each interrupt (tick): counters (PFM_COUNTERS), IPL histogramming (PFM_IPL), and user or kernel PC profiling (PFM_PROFILING).  These values are defined in <sys/pfcntr.h>, and can be selected orthogonally by bitwise OR’ing the selections together and passing to the PCNTSETITEMS ioctl. 

If counters are enabled, the interrupt count for this event is incremented.  This records the number of times each event has happened, in multiples of the interrupt frequency selected (PCNTSETMUX).  Note that the driver can only count the interrupts generated.  There is no direct access to the on-chip counter values. 

If IPL histogramming is enabled, the appropriate entry in the IPL array is incremented.  The entries are: 0-5 refer to IPL0-IPL5. 6 is unused (IPL6 is the level of the performance counter interrupts). 7 counts "idle" ticks (IPL == 0 and current_thread == idle_thread). 8 counts user mode ticks. 

If profiling is enabled, a PC sample is added to the profile histogram if the mode is correct (kernel or user). 

Since each CPU in a multi-processor platform has separate counters, there are three different ways to open the device: PCNTOPENONE opens and collects data on only this one CPU, PCNTOPENEACH opens all CPUs but keeps data for each one separately, and PCNTOPENALL opens all CPUs, aggregating the data for all CPUs into one collection.  These values are defined in <sys/pfcntr.h>, and are bitwise OR’d into the mode passed to the device open call.  Note that if PCNTOPENONE is selected, the opening thread/process must be bound to that processor, or the open will fail.  It must also remain bound to that processor for the duration of the driver usage or extremely unpredictable results will happen. 

The following ioctl calls apply to the performance counter pseudo-device:

PCNTRDISABLE
Disable performance counter interrupts on the CPU.  Takes no arguments.

PCNTRENABLE
Enable performance counter interrupts on the CPU.  Takes no arguments.

PCNTSETMUX
Select the statistics to be counted by each performance counter, and the interrupt frequency.  Takes a pointer to a struct iccsr which contains the MUX register values desired.  The fields in this register are:

iccsr_pc0
Controls the interrupt frequency of performance counter 0. If set, interrupt every 2^12 events. If clear, interrupt every 2^16 events.

iccsr_pc1
Controls the interrupt frequency of performance counter 1. If set, interrupt every 2^8 events. If clear, interrupt every 2^12 events.

iccsr_mux0
Selects the event counted by counter 0. One of:
PF_ISSUES, PF_PIPEDRY, PF_LOADI, PF_PIPEFROZEN, PF_BRANCHI, PF_CYCLES, PF_PALMODE, PF_NONISSUES, PF_EXTPIN0

iccsr_mux1
Selects the event counted by counter 1. One of:
PF_DCACHE, PF_ICACHE, PF_DUAL, PF_BRANCHMISS, PF_FPINST, PF_INTOPS, PF_STOREI, PF_EXTPIN1

iccsr_disable
Contains two bits, each of which disables data collection on the specified counter.  For example, set to 2 to disable counter 1 and enable counter 0. Cannot be set to 3 (would disable both counters; PCNTSETMUX will return EINVAL).

iccsr_ign0, iccsr_ign1, iccsr_ign2, iccsr_ign3
Do not set these fields.  Must be zero.

PCNTSETITEMS
Selects the data items to be collected at each tick:  counters (PFM_COUNTERS), IPL histogramming (PFM_IPL), and user or kernel PC profiling (PFM_PROFILING - see PCNTSETUADDR and PCNTSETKADDR).  These values are defined in <sys/pfcntr.h>, and can be selected orthogonally by bitwise OR’ing the selections together into the integer argument.  If no items are selected, returns EINVAL. 

PCNTLOGALL
Turn on the on-chip counters, setting them to count all system activity. Interrupts must be enabled first with PCNTENABLE.  Takes no arguments, returns no errors.

PCNTLOGSELECT
Turn on the on-chip counters, setting them to count only those threads/processes with the PCB_PME_BIT set in their PCB’s, and sets the PCB_PME_BIT for this process.  This bit is inherited across fork/exec, setting it for all children.  Interrupts must be enabled first with PCNTENABLE.  Takes no arguments, returns no errors.

PCNTCLEARCNT
Clears the driver’s internal counters appropriate to the actions selected.  If PFM_COUNTERS is enabled, the interrupt counters and cycle counter value are reset.  If PFM_IPL is enabled, the IPL histogram is reset.  If neither is enabled (PFM_PROFILING only), EINVAL is returned and nothing is cleared.  Takes no arguments.

PCNTGETCNT
Returns the current counter values and the pcc value(s).  Takes a pointer to an array of struct pfcntrs; the array is filled in with the values.  Sample usage of this ioctl is:

struct pfcntrs cntrs[NCPUS];
struct pfcntrs ∗pfcntrs = cntrs;
ioctl (fd, PCNTGETCNT, &pfcntrs);

If the driver is opened in mode PCNTOPENEACH, the underlying array must be big enough to hold all of the data for each CPU, or EFAULT is returned.  If the driver is opened in mode PCNTOPENONE or PCNTOPENALL, the array need only be one element. If PFM_COUNTER is not enabled, returns EINVAL. 

PCNTGETRSIZE
Return the number of bytes of data available to read for getting the PC profiling data.  This will be equal to one fourth of the address range being profiled (profiling data is kept as one bucket per four instructions).  If the driver is opened in mode PCNTOPENEACH, this will be multiplied by the number of CPUs.  To set the address range (and select user or kernel profiling), use the PCNTSETUADDR or PCNTSETKADDR ioctl.  Takes a pointer to a long, returns no errors.  The returned value will be 0 if profiling is not currently selected or the address range and mode have not been specified.

PCNTGETIPLHIS
Returns the current IPL histogram(s).  Takes a pointer to an array of struct pfipls; the array is filled in with the values.  Sample usage of this ioctl is:

struct pfipls ipls[NCPUS];
struct pfipls ∗pfipls = ipls;
ioctl (fd, PCNTGETIPLHIS, &pfipls);

If the driver is opened in mode PCNTOPENEACH, the underlying array must be big enough to hold all of the data for each CPU. If the underlying array is not big enough, EFAULT might be returned or other data in the program might be overwritten.  If the driver is opened in mode PCNTOPENONE or PCNTOPENALL, the array need only be one element.  If PFM_IPL is not enabled, returns EINVAL.

PCNTSETKADDR
Sets the kernel address range to profile, and turns on kernel mode PC profiling.  The device must be open for profiling, or EINVAL is returned.  If memory cannot be obtained for the sample data, ENOMEM is returned.

PCNTSETUADDR
Sets the user address range to profile, and turns on user mode PC profiling.  The device must be open for profiling, or EINVAL is returned.  If memory cannot be obtained for the sample data, ENOMEM is returned. Only one process may have the pfm device open at a time.  If the device is opened with PCNTOPENONE, only this CPU is considered open; subsequent open attempts will return EBUSY.  If the device is opened with PCNTOPENALL or PCNTOPENEACH, all CPUs must be available or EBUSY is returned.  It is sufficient to open the device read-only.  Opening the device will disable interrupts (PCNTDISABLE), and default to logging all system activity (PCNTLOGALL), generating simple counters only.  The counters are not cleared.  Closing the device automatically disables interrupts and resets the service routines (PCNTDISABLE).

DETAILED STAT DESCRIPTIONS

Following are more detailed descriptions of each of the events that can be counted by the 2 on-chip counters.  For more information, consult the 21064 chip specification. 

Issues(Total Issues Divided By 2) This counter is incremented by one for each cycle in which two instructions are issued and is incremented by 1/2 for each cycle in which one instruction is issued.  The number of cycles in which one instruction is issued can be found by using the Dual Issues field and the equation S = (I - D) ∗ 2, where S = Single Issues, D = Dual Issues, and I = Issues. 

PipedryThis counter is incremented by one for each cycle in which nothing is issued due to the lack of valid instruction stream data.  The causes could be instruction cache refill operations (due to normal sequential operation, or delays while fetching the target of a branch) or delays caused by the draining of the pipeline in response to an exception. 

LoadsThis counter is incremented once per issuance of a load instruction.  Note: If a load misses in the primary data cache, the replay of the instruction will cause the load counter to be incremented again. 

Pipefrozen
This counter is incremented by one for each cycle in which nothing is issued due to a resource conflict within the pipeline.  Examples are:

       •Not all source and destination registers are available

       •A load miss or write buffer overflow occurs

       •A conditional branch cannot be issued in the cycle following a jump

       •Memory Barrier instruction processing can cause the pipe to freeze

BranchesThis counter is incremented once per issuance of a branch instruction. 

CyclesThis counter is incremented once per cycle.  It is useful when determining whether or not the performance counters are operating properly. 

PALcycles
This counter is incremented once for each cycle spent in PALmode.

Nonissues
(Total Non-issues Divided By 2): This counter is incremented by one for each cycle in which no instructions are issued and is incremented by 1/2 for each cycle in which only one instruction is issued.  This counter is the inverse of the Issues counter: Non-issues = 1 - Issues.

VictimsExternal Pin 0: This counter is incremented once per external event supplied to external pin 0.  On the DEC 3000/500 and DEC 3000/400, this pin is connected to logic that indicates external cache misses with victims.  A victim is a data block that must be written back to main memory before it is reused. 

DcacheThis counter is incremented once per primary data cache miss.  Note: this counter actually is incremented each time a primary data cache probe does not complete in one cycle.  This includes all misses, but also includes hits that are stalled for other reasons such as bus traffic holding previously misses pending. 

IcacheThis counter is incremented once per primary instruction cache miss. 

Dualissues
This counter is incremented once per cycle where two instructions are dual-issued.

Mispredicts
This counter is incremented once per incorrectly predicted branch.

FloatopsThis counter is incremented once per floating point operate instructions.  The floating point operate instructions do not include the floating point load, floating point branch and floating point store instructions. 

IntopsThis counter is incremented once per integer operate instruction as well as once per Load Address and Load Address High instruction. 

StoresThis counter is incremented once per store instruction. 

Novictims
External Pin 1: This counter is incremented once per external event supplied to external pin 1.  On the DEC 3000/500 and DEC 3000/400, this pin is connected to logic that indicates external cache misses without victims. Most items count the instances of different types of instructions. These counters are incremented once per occurrence, and they do not give information about the cost of executing the instruction.  The Pipe Frozen/Dry counter increments once per frozen or dry cycle, not once per instance of pipe freeze or pipe dry.

NOTES

Disabling a counter cannot actually disable it from interrupting the CPU.  However, the interrupt will be dismissed without recording any data. 

Connections of the CPU’s PERF_CNT_H lines to external events are platform dependent.  Currently, only the DEC 3000/400,/500,/600,/800 workstations have these connections; they count BCache Misses and BCache Misses with Victims. 

Generating statistics on a per-process basis is only possible on 21064 Pass 3 or later processors.  Attempts to do this on a Pass 2 or earlier will gather statistics for the entire system. 

FILES

/dev/pfcntr - The device entry (character, dev# 26/0)
/usr/include/sys/pfcntr.h - structure definitions

RELATED INFORMATION

Commands: kprofile(1), uprofile(1), prof(1)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026