Source code upload

This commit is contained in:
calmsacibis995
2022-09-29 17:59:04 +03:00
parent 72fa9da3d7
commit 8fc8fa8089
33399 changed files with 11964078 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
#!smake
#ident "$Revision: 1.5 $"
include $(ROOT)/usr/include/make/commondefs
CFILES = evctr.c evctr_util.c ecadmin.c ecstats.c disp.c report.c
TARGETS = ecadmin ecstats
LCOPTS = -fullwarn $(INCDIRS)
LLDLIBS = -lgen
default: $(TARGETS)
include $(COMMONRULES)
install: default
$(INSTALL) -idb "mach(CPUARCH=R10000)" -m 555 -F /usr/etc ecadmin ecstats ecfind
evctr: evctr.o evctr_util.o
$(CC) $(COPTS) $(LDOPTS) -o $@ evctr.o evctr_util.o $(LDLIBS)
ecadmin: ecadmin.o evctr_util.o
$(CC) $(COPTS) $(LDOPTS) -o $@ ecadmin.o evctr_util.o $(LDLIBS)
ecstats: ecstats.o evctr_util.o disp.o report.o
$(CC) $(COPTS) $(LDOPTS) -o $@ ecstats.o evctr_util.o disp.o report.o $(LDLIBS) -lcurses
refresh:
rm -f procfs.h
rcp -p babylon.engr:/build/spb/t513/irix/kern/fs/procfs/procfs.h .
rm -f syssgi.h
rcp -p babylon.engr:/build/spb/t513/irix/kern/sys/syssgi.h .
rm -f hwperfmacros.h
rcp -p babylon.engr:/build/spb/t513/irix/kern/sys/hwperfmacros.h .
rm -f hwperftypes.h
rcp -p babylon.engr:/build/spb/t513/irix/kern/sys/hwperftypes.h .
+298
View File
@@ -0,0 +1,298 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Revision: 1.4 $"
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <curses.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include "evctr_util.h"
extern int Cflag;
#define BOS (LINES-1) /* Index of last line on screen */
enum cmode {ABSOLUTE, RATE} cmode;
static int Full;
extern void quit(int);
extern void fail(char *, ...);
static int Cfirst = 1;
void
quit(int stat)
{
if (Cflag) {
move(BOS, 0);
clrtoeol();
refresh();
(void)endwin();
}
exit(stat);
}
void
sig_winch(int sig)
{
if (Cflag) {
(void)endwin();
initscr();
Cfirst = 1;
}
/* re-arm in case we have System V signals */
(void)signal(sig, sig_winch);
}
void
fail(char *fmt, ...)
{
va_list args;
if (Cflag) {
move(BOS, 0);
clrtoeol();
refresh();
endwin();
}
va_start(args, fmt);
fprintf(stderr, "ecstat: ");
vfprintf(stderr, fmt, args);
va_end(args);
exit(1);
}
void
do_display(int interval)
{
int ystart = 1;
int y;
int x;
int ctr;
move(ystart, 0);
standout();
if (cmode == ABSOLUTE)
printw("%18s Event Code and Name", "Absolute Count");
else
printw("%18s Event Code and Name", "Delta Count/sec");
getyx(stdscr, y, x);
move(y, x);
while (x < COLS-1) {
addch(' ');
x++;
}
standend();
evctr_global_sample(0);
if (ActiveChanged || Cfirst) {
for (y = ystart+1; y < BOS; y++) {
move(y, 0);
clrtoeol();
}
Cfirst = 1;
}
y = ystart;
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (!Full && !Active[ctr])
continue;
y++;
if (y < BOS) {
move(y, 0);
if (Active[ctr]) {
if (cmode == ABSOLUTE)
printw("%18llu", Count[ctr] * Mux[ctr]);
else {
if (OldCount[ctr] != -1)
printw("%18.2f", (double)((Count[ctr] - OldCount[ctr]) * Mux[ctr]) / interval);
else
printw("%18s", "<initializing>");
}
addch(' ');
if (Sem[ctr] != EVCTR_SEM_OK)
addch('?');
else if (Mux[ctr] > 1)
addch('*');
else
addch(' ');
OldCount[ctr] = Count[ctr];
}
else if (Cfirst)
printw("%18s ", "<inactive>");
if (Cfirst)
printw(" [%2d] %s", ctr, EventDesc[ctr].text);
}
}
}
const char ctrl_l = 'L' & 037;
/*
* Repeated periodic Curses display
*/
void
disp(int fflag, int rflag, int interval, int samples)
{
time_t now;
char tmb[80];
struct timeval wait;
fd_set rmask;
struct termio tb;
int c, n;
int intrchar; /* user's interrupt character */
int suspchar; /* job control character */
static char rtitle[] = "R: rate";
static char atitle[] = "A: absolute";
static char host[20] = "";
gethostname (host, sizeof(host));
Full = fflag ? 1 : 0;
cmode = rflag ? RATE : ABSOLUTE;
(void) ioctl(0, TCGETA, &tb);
intrchar = tb.c_cc[VINTR];
suspchar = tb.c_cc[VSUSP];
FD_ZERO(&rmask);
/* now that everything else is ready, leave cooked mode
*/
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
leaveok(stdscr, FALSE);
nonl();
intrflush(stdscr, FALSE);
move(0, 0);
(void)signal(SIGINT, quit);
(void)signal(SIGTERM, quit);
(void)signal(SIGHUP, quit);
(void)signal(SIGWINCH, sig_winch);
for (;;) {
if (Cfirst) {
clear();
standout();
move(BOS, 0);
printw(
"F:AllCtrs E:EnabledCtrs R:Rate A:Absolute");
standend();
switch (cmode) {
case RATE:
move(0, 80-sizeof(rtitle));
printw(rtitle);
break;
case ABSOLUTE:
move(0, 80-sizeof(atitle));
printw(atitle);
break;
}
}
now = time(0);
cftime(tmb, "%b %e %T", &now);
move(0, 0);
printw("Global Event Counters -- %s -- %s", tmb, host);
do_display(interval);
Cfirst = 0;
move(0, 0);
refresh();
if (samples) {
if (samples == 1) {
/*
* all done, so exit
*/
quit(0);
/*NOTREACHED*/
}
samples--;
}
(void)gettimeofday(&wait, 0);
wait.tv_sec = interval-1;
wait.tv_usec = 1000000 - wait.tv_usec;
if (wait.tv_usec >= 1000000) {
wait.tv_sec++;
wait.tv_usec -= 1000000;
}
if (wait.tv_sec < interval
&& wait.tv_usec < 1000000/10)
wait.tv_sec++;
FD_SET(0, &rmask);
n = select(1, &rmask, NULL, NULL, &wait);
if (n < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
fail("select: %s\n", strerror(errno));
break;
}
else if (n == 1) {
c = getch();
if (c == intrchar || c == 'q' || c == 'Q') {
quit(0);
/*NOTREACHED*/
}
if (samples) samples++;
if (c == suspchar) {
reset_shell_mode();
kill(getpid(), SIGTSTP);
reset_prog_mode();
}
else if (c == 'a' || c == 'A') {
cmode = ABSOLUTE;
Cfirst = 1;
}
else if (c == 'e' || c == 'E') {
Full = 0;
Cfirst = 1;
}
else if (c == 'f' || c == 'F') {
Full = 1;
Cfirst = 1;
}
else if (c == 'r' || c == 'R') {
cmode = RATE;
Cfirst = 1;
}
else if (c == ctrl_l) {
Cfirst = 1;
}
}
}
}
+146
View File
@@ -0,0 +1,146 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Id: ecadmin.c,v 1.5 1998/12/16 23:03:45 kenmcd Exp $"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/times.h>
#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libgen.h>
#include <signal.h>
#include <errno.h>
#include <pwd.h>
#include <time.h>
#include "evctr_util.h"
void
main(int argc, char **argv)
{
int done_init = 0;
int sts = 0;
int c;
int rflag = 0;
int lflag = 0;
int mixed = 0;
int setflag = 0;
char *cmd = basename(argv[0]);
extern char *optarg;
extern int optind;
extern int evctr_debug;
/* check options; */
while ((c = getopt(argc, argv, "ad:De:lMrT?")) != EOF)
switch(c) {
case 'a': setflag = 1;
if (!done_init) {
evctr_init(cmd);
done_init = 1;
}
evctr_opt("*", 1);
break;
case 'd': setflag = 1;
if (!done_init) {
evctr_init(cmd);
done_init = 1;
}
evctr_opt(optarg, -1);
break;
case 'D': evctr_debug = 1;
break;
case 'e': setflag = 1;
if (!done_init) {
evctr_init(cmd);
done_init = 1;
}
evctr_opt(optarg, 1);
break;
case 'l': lflag = 1;
break;
case 'M': /* mixed R10K and R12K is OK */
fprintf(stderr, "%s: Warning: -M allows statistically questionable counter combinations\n", cmd);
mixed = 1;
break;
case 'r': rflag = 1;
break;
case 'T': /* trust me */
fprintf(stderr, "%s: Warning: -T allows semantically questionable counter combinations\n", cmd);
evctr_trustme();
break;
case '?': goto use;
}
if (optind <= argc - 1)
goto use;
if (rflag + setflag + lflag == 0)
goto use;
if (!done_init) {
evctr_init(cmd);
done_init = 1;
}
if (cpucount.r10k > 0 && cpucount.r12k > 0 && mixed == 0) {
fprintf(stderr, "ecadmin: Error: counters for mixed R10000 and R12000 systems is not supported\n");
exit(1);
}
if (lflag)
evctr_global_status(stdout);
if (rflag + setflag != 0) {
if (cap_envl(0, CAP_DEVICE_MGT, (cap_value_t) 0) == -1) {
fprintf(stderr, "ecadmin: Error: cannot change counter setup: %s\n", strerror(errno));
exit(1);
}
}
if (rflag) {
if (evctr_global_release() == 0)
sts = 1;
}
if (setflag) {
if (evctr_global_set() == 0)
sts = 1;
}
exit(sts);
use:
fprintf(stderr, "Usage: ecadmin [-aDlrT] [-d event,[event]...] [-e event,[event]...]\n");
exit(1);
}
+199
View File
@@ -0,0 +1,199 @@
#!/bin/sh
#
# Copyright 1998, Silicon Graphics, Inc.
# ALL RIGHTS RESERVED
#
# UNPUBLISHED -- Rights reserved under the copyright laws of the United
# States. Use of a copyright notice is precautionary only and does not
# imply publication or disclosure.
#
# U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
# Use, duplication or disclosure by the Government is subject to restrictions
# as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
# in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
# in similar or successor clauses in the FAR, or the DOD or NASA FAR
# Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
# 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
#
# THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
# INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
# DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
# PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
# GRAPHICS, INC.
#
# Report processes currently using process-based event counters
#
# $Id: ecfind,v 1.1 1998/12/06 23:38:00 kenmcd Exp $
_usage()
{
echo "Usage: ecfind [-tv]"
}
PATH=/bin:/usr/bin
export PATH
verbose=false
terse=false
while getopts "tv?" c
do
case $c
in
t) terse=true
;;
v) verbose=true
;;
?) _usage
exit 0
;;
esac
done
shift `expr $OPTIND - 1`
if [ $# -ne 0 ]
then
_usage
exit 1
fi
# have to be R10K or R12K for event counters to be available
#
if hinv -t cpu | egrep 'R10000|R12000' >/dev/null
then
:
else
echo "ecfind: Error, event counters only supported on R10000 or R12000 CPUs"
exit 1
fi
# have to be root to make any progress
#
id=`id | sed -e "s/(.*//" -e "s/.*=//"`
if [ "$id" != 0 ]
then
echo "ecfind: Error, to report process-based event counter use, you must be root"
exit 1
fi
tmp=/var/tmp/$$
status=0
trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
# Notes:
# 1. 0x9 in last filter comes from (HWPERF_CM_ENABLED | HWPERF_CM_PROC)
# see <sys/hwperftypes.h>
# 2. for some icrash versions, output contains '>> ' prefix, sed is
# used to strip these out
# 3. sometimes icrash adds carriage return (^M) suffix, tr is used to
# strip these out
# 4. -e cmd not supported by all icrash versions, hence
# ( cmds ...; echo quit ) | icrash
#
# icrash version and kernel data structure checks
# the "px deadbeef" command adds a marker to separate the two sections
# of output, so we only need to run icrash once here
#
( echo '?' \
; echo 'px deadbeef' \
; echo 'whatis (uthread_t *)0' \
; echo 'whatis (uthread_t *)0->ut_perfmon' \
; echo 'whatis (uthread_t *)0->ut_perfmon.pm_cpu_mon' \
; echo 'whatis (uthread_t *)0->ut_perfmon.pm_cpu_mon->cm_flags' \
; echo quit \
) \
| icrash 2>&1 \
| tr -d '\015' >$tmp.tmp
if sed -e '/0xdeadbeef/q' <$tmp.tmp | egrep uthread >/dev/null
then
# icrash suports uthread command
:
else
# oops
#
echo "ecfind: Cannot find processes using event counters ..."
echo " The version of icrash (`icrash -v 2>&1`) on IRIX `uname -R 2>&1`"
echo " does not support the \"uthread\" command required for this script"
echo " to operate correctly."
status=1
exit
fi
if egrep '(Syntax error)|(No such member)' $tmp.tmp >/dev/null
then
# the uthread definition would appear to have changed
#
echo "ecfind: Cannot find processes using event counters ..."
echo " The kernel thread data structures would appear to have changed"
echo " and the required flags cannot be located."
echo " The following output from icrash may help diagnose how this"
echo " script needs to be changed:"
sed -e '1,/0xdeadbeef/d' -e 's/^/ /' $tmp.tmp
status=1
exit
fi
# output from the icrash uthread command and the mapping to sed's
# substrings
#
# a800000102bbc000 2152040 0 0 pmcd
# \1 \2 \3 \4 \5
#
# this becomes the icrash command
#
# px "2152040","pmcd",(uthread_t *)a800000102bbc000->ut_perfmon.pm_cpu_mon->cm_flags
#
# to which icrash responds thus ...
#
# 2152040 pmcd 0x409b
#
( echo uthread; echo quit ) \
| icrash 2>&1 \
| tr -d '\015' \
| tee $tmp.uthread \
| ( sed -n \
-e 's/^>> //' \
-e '/^[ 0-9a-f][ 0-9a-f][ 0-9a-f][ 0-9a-f][ 0-9a-f][ 0-9a-f][ 0-9a-f][ 0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f] /{
s/\([^ ][^ ]*\) *\([^ ][^ ]*\) *\([^ ][^ ]*\) *\([^ ][^ ]*\) *\([^ ][^ ]*\).*/px "\2","\5",(uthread_t *)\1->ut_perfmon.pm_cpu_mon->cm_flags/
p
}' \
; echo quit \
) \
| tee $tmp.icmds \
| icrash 2>&1 \
| tee $tmp.flags \
| sed -n \
-e 's/^>> //' \
-e 's/␍//' \
-e '/^[0-9].* 0x9$/s/ 0x9$//p' \
| sort -n >$tmp.terse
if $terse
then
cat $tmp.terse
else
if [ -s $tmp.terse ]
then
echo "Processes using process-based event counters ..."
echo "NR == 1 { print }" >$tmp.nawk
nawk '{ print "$2 == " $1 " { print }" }' <$tmp.terse >>$tmp.nawk
ps -ef \
| nawk -f $tmp.nawk
else
echo "No processes are using process-based event counters."
fi
fi
if $verbose
then
echo
echo "Output from icrash \"uthread\" command ..."
cat $tmp.uthread
echo
echo "Input to icrash ..."
cat $tmp.icmds
echo
echo "Threads, pids, command name and flags ..."
cat $tmp.flags
fi
+124
View File
@@ -0,0 +1,124 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Id: ecstats.c,v 1.5 1998/12/06 23:07:24 kenmcd Exp $"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "evctr_util.h"
int Cflag;
void main(int argc, char **argv)
{
int c;
char *p;
int samples = 0;
int delta = 5;
int fflag = 0;
int rflag = 1;
extern char *optarg;
extern int optind;
extern int evctr_debug;
extern void disp(int, int, int, int);
extern void report(int, int, int);
evctr_init(argv[0]);
/* check options; */
while ((c = getopt(argc, argv, "aCDefrs:?")) != EOF) {
switch(c) {
case 'a': rflag = 0;
break;
case 'C': Cflag = 1; /* full screen */
break;
case 'D': evctr_debug = 1;
break;
case 'e': fflag = 0;
break;
case 'f': fflag = 1; /* full (all) events */
break;
case 'r': rflag = 1; /* counter rate */
break;
case 's': /* limited samples */
samples = (int)strtol(optarg, &p, 10);
if (*p != '\0' || samples <= 0) {
fprintf(stderr, "ecstats: \"samples\" (%s) illegal, must be a positive integer\n",
optarg);
exit(1);
}
break;
case '?':
goto use;
}
}
if (optind < argc-1)
goto use;
if (optind == argc-1) {
delta = strtol(argv[optind], &p, 10);
if (*p != '\0' || delta <= 0) {
fprintf(stderr, "ecstats: \"interval\" (%s) illegal, must be a positive integer\n",
argv[optind]);
exit(1);
}
}
if (samples != 0) {
if (rflag == 1)
/* rates need one more iteration */
samples++;
}
if (Cflag) {
disp(fflag, rflag, delta, samples);
/*NOTREACHED*/
}
for ( ; ; ) {
evctr_global_sample(1);
report(fflag, rflag, delta);
if (samples) {
if (samples == 1)
/*
* all done, so exit
*/
exit(0);
samples--;
}
sleep(delta);
}
use:
fprintf(stderr, "Usage: ecstats [-aCDefr] [-s samples] [interval]\n");
exit(1);
}
+246
View File
@@ -0,0 +1,246 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Id"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <time.h>
#include "evctr_util.h"
extern int errno;
extern char *sys_errlist[];
static char quant[] = { HZ/10, 10, 10, 6, 10, 6, 10, 10, 10 };
static char *pad = "000 ";
static char *sep = "\0\0.\0:\0:\0\0";
static char *nsep = "\0\0.\0 \0 \0\0";
void
printt(char *s, time_t a)
{
char digit[9];
register int i;
char c;
int nonzero;
for (i=0; i<9; i++) {
digit[i] = (char)a % quant[i];
a /= quant[i];
}
fprintf(stderr,s);
nonzero = 0;
while (--i>0) {
c = digit[i]!=0 ? digit[i]+'0':
nonzero ? '0':
pad[i];
if (c != '\0') putc(c,stderr);
nonzero |= digit[i];
c = nonzero?sep[i]:nsep[i];
if (c != '\0') putc(c,stderr);
}
fprintf(stderr,"%c",digit[0]*100/HZ+'0');
fprintf(stderr,"\n");
}
/*
** hmstime() sets current time in hh:mm:ss string format in stime;
*/
void
hmstime(char *stime)
{
char *ltime;
time_t tme;
tme = time((time_t *)0);
ltime = ctime(&tme);
strncpy(stime, ltime+11, 8);
stime[8] = '\0';
}
void
diag(char *s)
{
fprintf(stderr,"%s\n",s);
exit(1);
}
/* ARGSUSED */
static void
onintr(int dummy)
{
}
void main(argc, argv)
int argc;
char **argv;
{
struct tms buffer, obuffer;
int status;
register int p;
int c;
time_t before, after;
/* char stime[9], etime[9];*/
/* char cmd[80];*/
extern char *optarg;
extern int optind;
int i;
char *op;
int tflg = 0;
int delta;
int eflg = 1;
pid_t pid = -1; /* for -p pid */
int excp = 0; /* -x (exception level ctrs) */
int iter = -1; /* -r (repeat) */
evctr_init(argv[0]);
/* check options; */
while ((c = getopt(argc, argv, "e:p:r:t:x?")) != EOF) {
switch(c) {
case 'e':
evctr_opt(optarg, 1);
break;
case 'p':
pid = (int)strtol(optarg, &op, 10);
if (*op != '\0')
/* not a number */
diag("-p requires numeric pid argument");
break;
case 'r':
iter = (int)strtol(optarg, &op, 10);
if (*op != '\0')
/* not a number */
diag("-r requires numeric argument");
break;
case 't':
delta = (int)strtol(optarg, &op, 10);
if (*op != '\0')
/* not a number */
diag("-t requires numeric argument");
break;
case 'x':
excp = 1;
break;
case '?': diag("Usage: evctr [-e event,[event]...] [-x] cmd [args]\n evctr [-e event,[event]...] [-r iter] [-t delta] [-x] -p pid");
break;
}
}
if (pid == -1 && optind >= argc) diag("Missing command");
if (tflg && pid == -1) diag("-t option requires -p pid");
if (iter != -1 && !tflg) diag("-r option requires -t delta");
/* TODO - if pid != -1, this is not correct */
before = times(&obuffer);
if (eflg) {
pid_t lpid = pid;
if (lpid == -1)
lpid = getpid();
if (!evctr_start(lpid, excp)) {
if (pid != -1)
exit(1);
fprintf(stderr, "evctr: Warning: failed to initialize event counters: %s\n", strerror(errno));
eflg = 0;
}
}
if (pid == -1) {
if ((p = fork()) == -1) diag("Try again.\n");
if (p == 0) {
setgid(getgid());
execvp(*(argv+optind),(argv+optind));
fprintf(stderr, "%s: %s\n", *(argv+optind), sys_errlist[errno]);
exit(1);
}
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
while (wait(&status) != p);
if ((status&0377) != 0)
fprintf(stderr,"Command terminated abnormally.\n");
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
}
else {
if (!tflg) {
fprintf(stderr, "Watching process %d ...", pid);
signal(SIGINT, onintr);
pause();
fprintf(stderr, " done watching\n");
}
else {
i = 0;
for (i = 0; iter == -1 || i < iter; i++) {
sleep(delta);
if (iter == -1 || i+1 < iter)
break;
if (!evctr_sample()) {
eflg = 0;
break;
}
fprintf(stderr,"\n");
evctr_report(stderr);
}
}
}
if (eflg) {
if (evctr_sample()) {
fprintf(stderr,"\n");
evctr_report(stderr);
}
}
if (pid != -1)
evctr_release();
after = times(&buffer);
fprintf(stderr,"\n");
printt("real", (after-before));
if (pid != -1)
fprintf(stderr, "Warning: CPU times are bogus at the moment\n");
printt("user", buffer.tms_cutime - obuffer.tms_cutime);
printt("sys ", buffer.tms_cstime - obuffer.tms_cstime);
fprintf(stderr,"\n");
exit(status>>8);
}
+675
View File
@@ -0,0 +1,675 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Id: evctr_util.c,v 1.7 1999/04/30 15:24:33 steiner Exp $"
#include <sys/types.h>
#include <sys/stat.h>
#include <procfs/procfs.h>
#include <sys/syssgi.h>
#include <sys/systeminfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include "evctr_util.h"
EventDesc_t DescR10K[] = {
{ HWPERF_C0PRFCNT0_CYCLES, "CYCLES", "Cycles" },
{ HWPERF_C0PRFCNT0_IINSTR, "INSTRI", "Instructions issued" },
{ HWPERF_C0PRFCNT0_ILD, "LOADI", "Loads, etc. issued" },
{ HWPERF_C0PRFCNT0_IST, "STOREI", "Stores issued" },
{ HWPERF_C0PRFCNT0_ISC, "SCONDI", "Store conditionals issued" },
{ HWPERF_C0PRFCNT0_FAILSC, "SCONDF", "Store conditionals failed" },
{ HWPERF_C0PRFCNT0_DECBR, "BRD", "Branches decoded" },
{ HWPERF_C0PRFCNT0_QWWSC, "WB2$", "Quadwords written back from scache" },
{ HWPERF_C0PRFCNT0_SCDAECC, "ECC2$", "Single-bit ECC errors on scache data" },
{ HWPERF_C0PRFCNT0_PICMISS, "1$IMISS", "Pcache instruction misses" },
{ HWPERF_C0PRFCNT0_SICMISS, "2$IMISS", "Scache instruction misses" },
{ HWPERF_C0PRFCNT0_IMISPRED,"2$IWAYMP", "Scache instruction way misprediction" },
{ HWPERF_C0PRFCNT0_EXTINT, "INT", "External intervention requests" },
{ HWPERF_C0PRFCNT0_EXTINV, "INV", "External invalidate requests" },
{ HWPERF_C0PRFCNT0_VCOH, "FUCOMP", "ALU/FPU completion cycles" },
{ HWPERF_C0PRFCNT0_GINSTR, "INSTRG", "Instructions graduated" },
{ HWPERF_C0PRFCNT1_CYCLES, "CYCLES", "Cycles" },
{ HWPERF_C0PRFCNT1_GINSTR, "INSTRG", "Instructions graduated" },
{ HWPERF_C0PRFCNT1_GLD, "LOADG", "Loads graduated" },
{ HWPERF_C0PRFCNT1_GST, "STOREG", "Stores graduated" },
{ HWPERF_C0PRFCNT1_GSC, "SCONDG", "Store conditionals graduated" },
{ HWPERF_C0PRFCNT1_GFINSTR, "FPG", "Floating point instructions graduated" },
{ HWPERF_C0PRFCNT1_QWWPC, "WB1$", "Quadwords written back from pcache" },
{ HWPERF_C0PRFCNT1_TLBMISS, "TLBMISS", "TLB refill exceptions" },
{ HWPERF_C0PRFCNT1_BRMISS, "BRMP", "Branches mispredicted" },
{ HWPERF_C0PRFCNT1_PDCMISS, "1$DMISS", "Pcache data misses" },
{ HWPERF_C0PRFCNT1_SDCMISS, "2$DMISS", "Scache data misses" },
{ HWPERF_C0PRFCNT1_DMISPRED,"2$DWAYMP", "Scache data way misprediction" },
{ HWPERF_C0PRFCNT1_EXTINTHIT,"INTHIT", "External intervention hits in scache" },
{ HWPERF_C0PRFCNT1_EXTINVHIT,"INVHIT", "External invalidate hits in scache" },
{ HWPERF_C0PRFCNT1_SPEXCLEAN,"UPCLEAN", "Upgrade requests on clean scache lines" },
{ HWPERF_C0PRFCNT1_SPEXSHR, "UPSHARE", "Upgrade requests on shared scache lines" }
};
EventDesc_t DescR12K[HWPERF_EVENTMAX] = {
{ HWPERF_PRFCNT_CYCLES, "CYCLES", "Cycles" },
{ HWPERF_PRFCNT_DINSTR, "INSTRD", "Decoded instructions" },
{ HWPERF_PRFCNT_DLD, "LOADD", "Decoded loads" },
{ HWPERF_PRFCNT_DST, "STORED", "Decoded stores" },
{ HWPERF_PRFCNT_MTHO, "MHTO", "Miss Handling Table occupancy" },
{ HWPERF_PRFCNT_FAILSC, "SCONDF", "Failed store conditionals" },
{ HWPERF_PRFCNT_RESCB, "RESCBR", "Resolved conditional branches" },
{ HWPERF_PRFCNT_QWWSC, "WB2$", "Quadwords written back to scache" },
{ HWPERF_PRFCNT_SCDAECC, "ECC2$", "Correctable scache data array errors" },
{ HWPERF_PRFCNT_PICMISS, "1$IMISS", "Primary instruction cache misses" },
{ HWPERF_PRFCNT_SICMISS, "2$IMISS", "Secondary instruction cache misses" },
{ HWPERF_PRFCNT_IMISPRED, "2$IWAYMP", "Instruction misprediction from scache way predication table" },
{ HWPERF_PRFCNT_EXTINT, "INT", "External interventions" },
{ HWPERF_PRFCNT_EXTINV, "INV", "External invalidates" },
{ HWPERF_PRFCNT_ALUFPUFP, "ALUFPUP", "ALU/FPU forward progress" },
{ HWPERF_PRFCNT_GINSTR, "INSTRG", "Graduated instructions" },
{ HWPERF_PRFCNT_EXPREI, "INSTRPE", "Executed Prefetch Instructions" },
{ HWPERF_PRFCNT_PDCMISSPI, "1$DMPI", "Primary data cache misses by prefetch instructions" },
{ HWPERF_PRFCNT_GLD, "LOADG", "Graduated loads" },
{ HWPERF_PRFCNT_GST, "STOREG", "Graduated stores" },
{ HWPERF_PRFCNT_GSC, "SCONDG", "Graduated store conditionals" },
{ HWPERF_PRFCNT_GFINSTR, "FPG", "Graduated floating point instructions" },
{ HWPERF_PRFCNT_QWWPC, "WB1$", "Quadwords written back from primary data cache" },
{ HWPERF_PRFCNT_TLBMISS, "TLBMISS", "Translation lookaside buffer misses" },
{ HWPERF_PRFCNT_BRMISS, "BRMP", "Mispredicted branches" },
{ HWPERF_PRFCNT_PDCMISS, "1$DMISS", "Primary data cache misses" },
{ HWPERF_PRFCNT_SDCMISS, "2$DMISS", "Secondary data cache misses" },
{ HWPERF_PRFCNT_DMISPRED, "2$DWAYMP", "Data misprediction from scache way predication table" },
{ HWPERF_PRFCNT_EXTINTHIT, "INTHIT", "State of External intervention hits in scache" },
{ HWPERF_PRFCNT_EXTINVHIT, "INVHIT", "State of External invalidate hits in scache" },
{ HWPERF_PRFCNT_NHTAM, "NHTAM", "Miss Handling Table entries accessing memory" },
{ HWPERF_PRFCNT_SPEX, "2$SPEX", "Store/prefetch exclusive to block in secondary cache" }
};
EventDesc_t DescR10K_Rev2_Ev14 =
{ HWPERF_C0PRFCNT0_VCOH, "VCC", "Virtual coherency condition" };
EventDesc_t *EventDesc = DescR10K;
static hwperf_eventctrl_t evctr_set; /* counter control */
static hwperf_profevctrarg_t evctr_args_set; /* global counter control */
static hwperf_profevctrarg_t evctr_args_get; /* ditto */
static int gen; /* generation number */
static char *cmd; /* trimmed argv[0] */
static int trustme = 0;
cpucount_t cpucount;
int evctr_debug = 0;
int ActiveChanged;
int Active[HWPERF_EVENTMAX];
int Mux[HWPERF_EVENTMAX];
int Sem[HWPERF_EVENTMAX];
__uint64_t OldCount[HWPERF_EVENTMAX];
__uint64_t Count[HWPERF_EVENTMAX];
int Use[2]; /* mux count for each physical ctr */
static void
remap(hwperf_ctrl_t *cp)
{
int ctr;
/*
* try to remap if either counter is cycles(0,16) or
* graduated instructions(15,17)
* Warning ... this assumes we have only 2 physical registers, and is
* R10000-specific
*/
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (!cp[ctr].hwperf_spec)
continue;
if (ctr < HWPERF_CNT1BASE)
Use[0]++;
else
Use[1]++;
}
if (Use[0] > Use[1] + 1 && cp[0].hwperf_spec) {
cp[0].hwperf_spec = 0;
Use[0]--;
cp[16].hwperf_spec = 1;
Use[1]++;
}
if (Use[1] > Use[0] + 1 && cp[16].hwperf_spec) {
cp[16].hwperf_spec = 0;
Use[1]--;
cp[0].hwperf_spec = 1;
Use[0]++;
}
if (Use[0] > Use[1] + 1 && cp[15].hwperf_spec) {
cp[15].hwperf_spec = 0;
Use[0]--;
cp[17].hwperf_spec = 1;
Use[1]++;
}
if (Use[1] > Use[0] + 1 && cp[17].hwperf_spec) {
cp[17].hwperf_spec = 0;
Use[1]--;
cp[15].hwperf_spec = 1;
Use[0]++;
}
if (evctr_debug) {
fprintf(stderr, "After counter remap ...\n");
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ ) {
if (!cp[ctr].hwperf_spec)
continue;
fprintf(stderr, "Enable [%2d] %s %s\n", ctr, EventDesc[ctr].name, EventDesc[ctr].text);
}
}
}
/*
* report control ...
* 0 no messages
* 1 messages to stderr
*/
static int
check_semantics(int ctr, int report)
{
int sts = EVCTR_SEM_OK;
if (cpucount.r10k_rev2 > 0 && cpucount.r10k_rev3 > 0) {
/* mixed rev R10Ks */
if (ctr == 14) { /* Virtual coherency condition */
if (report) {
fprintf(stderr, "%s: Warning: counter %d has conflicting meaning:\n", cmd, ctr);
fprintf(stderr, "\tR10000 Rev. 2: %s\n", DescR10K_Rev2_Ev14.text);
fprintf(stderr, "\tR10000 Rev. 3: %s\n", DescR10K[ctr].text);
}
if (!trustme) {
sts = EVCTR_SEM_BAD;
}
else {
sts = EVCTR_SEM_R10K_REV;
}
}
}
if (cpucount.r10k > 0 && cpucount.r12k > 0) {
if (ctr == 1 || /* Issued instructions */
ctr == 2 || /* Issued loads */
ctr == 3 || /* Issued stores */
ctr == 4 || /* Issued store conditionals */
ctr == 5 || /* Failed store conditionals */
ctr == 6 || /* Decoded branches */
( ctr == 14 && cpucount.r10k_rev3 == 0) || /* Virtual coherency conditon */
ctr == 16 || /* Cycles */
ctr == 17 || /* Graduated instructions */
ctr == 30 || /* Store/prefetch exclusive to clean block in secondary cache */
ctr == 31) { /* Store/prefetch exclusive to shared block in secondary cache */
if (report) {
fprintf(stderr, "%s: Warning: counter %d has conflicting meaning:\n", cmd, ctr);
fprintf(stderr, "\tR10000: %s\n", DescR10K[ctr].text);
fprintf(stderr, "\tR12000: %s\n", DescR12K[ctr].text);
}
if (!trustme) {
sts = EVCTR_SEM_BAD;
}
else if (sts == EVCTR_SEM_OK) {
sts = EVCTR_SEM_R10K_R12K;
}
}
}
return sts;
}
void
evctr_init(char *myname)
{
static char *buf;
static int buflen = 0;
static char *template="RXX000 x.x, xxx"; /* contains a few extra chars just in case */
char *p_type;
char *ver;
int need;
int i;
int ncpu;
cmd = strdup(basename(myname));
if (buflen == 0) {
/*
* enough for 32 processors, expand as required below
*/
buflen = 32 * strlen(template);
if ((buf = (char *)malloc(buflen)) == NULL) {
fprintf(stderr, "%s: Error: malloc(%d): %s\n",
cmd, buflen, strerror(errno));
exit(1);
}
}
if (sysinfo(_MIPS_SI_NUM_PROCESSORS, buf, buflen) < 0) {
fprintf(stderr, "%s: Error: sysinfo(_MIPS_SI_NUM_PROCESSORS, ...): %s\n",
cmd, strerror(errno));
exit(1);
}
ncpu = atoi(buf);
if (ncpu <= 0 || ncpu > 4096) {
/* not reasonable */
fprintf(stderr, "%s: Error: number of CPUs from sysinfo (%d) is not believable\n",
cmd, ncpu);
exit(1);
}
need = ncpu * strlen(template);
if (need > buflen) {
buflen = need;
if ((buf = (char *)realloc(buf, buflen)) == NULL) {
fprintf(stderr, "%s: Error: realloc(..., %d): %s\n",
cmd, buflen, strerror(errno));
exit(1);
}
}
if (sysinfo(_MIPS_SI_PROCESSORS, buf, buflen) < 0) {
fprintf(stderr, "%s: Error: sysinfo(_MIPS_SI_PROCESSORS, ...): %s\n",
cmd, strerror(errno));
exit(1);
}
for (i = 0; i < ncpu; i++) {
if (i == 0)
p_type = strtok(buf, " ,");
else
p_type = strtok(NULL, " ,");
if (p_type == NULL)
break;
ver = strtok(NULL, " ,");
if (evctr_debug)
fprintf(stderr, "CPU[%d]: %s Rev. %s\n", i, p_type, ver == NULL ? "?" : ver);
if (strcmp(p_type, "R10000") == 0) {
/* Hw counter change in R10K from rev 2.x to rev 3.x !!
*
**** 14 = Virtual coherency conditions
* In rev 2.x this counter is incremented on the cycle after a virtual
* address coherence condition is detected, provided that the
* access was not flagged as a miss. This condition can only be
* realized for virtual page sizes of 4KB.
*
**** 14 = Functional unit completion cycles
* In rev 3.x this counter's meaning is changed. It is incremented on
* the cycle after either ALU1, ALU2, FPU1, or FPU2 marks an
* instruction as "done."
****
*/
int major;
int minor;
cpucount.r10k++;
if (ver != NULL) {
if (sscanf(ver, "%d.%d", &major, &minor) == 2) {
if (major == 2) {
cpucount.r10k_rev2++;
continue;
}
else if (major == 3) {
cpucount.r10k_rev3++;
continue;
}
}
}
fprintf(stderr, "%s: Error: R10000 unknown Rev. %s\n",
cmd, ver == NULL ? "<NULL>" : ver);
exit(1);
}
else if (strcmp(p_type, "R12000") == 0) {
cpucount.r12k++;
}
else {
fprintf(stderr, "%s: Error: counters not supported on %s CPUs\n", cmd, buf);
exit(1);
}
}
if (cpucount.r10k_rev2 > 0 && cpucount.r10k_rev3 == 0) {
/* remap to R10000 rev 2 semantics */
if (evctr_debug) {
fprintf(stderr, "%s: Warning: using R10000 Rev. 2 interpretation for counter 14\n", cmd);
fprintf(stderr, "\tR10000 Rev. 2: %s\n", DescR10K_Rev2_Ev14.text);
}
DescR10K[14] = DescR10K_Rev2_Ev14;
}
if (cpucount.r10k == 0 && cpucount.r12k > 0)
/* pure R12000 system */
EventDesc = DescR12K;
}
void
evctr_opt(char *optarg, int enable)
{
int ctr;
char *op;
char *p;
if (strcmp(optarg, "?") == 0) {
fprintf(stderr, "Available counters ...\n");
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ ) {
if (check_semantics(ctr, 0) == EVCTR_SEM_BAD)
continue;
fprintf(stderr, "[%2d] %-8s %s\n",
ctr, EventDesc[ctr].name, EventDesc[ctr].text);
}
exit(0);
}
if (strcmp(optarg, "*") == 0) {
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ ) {
if (check_semantics(ctr, 0) == EVCTR_SEM_BAD)
continue;
if (cpucount.r12k == 0 && (ctr == 15 || ctr == 16))
continue;
evctr_set.hwp_evctrl[ctr].hwperf_spec = enable;
}
return;
}
/*
* process comma separated list of counter numbers and/or names
*/
for ( ; ; ) {
for (p = optarg; *p && *p != ','; p++)
;
if (*p == ',')
/* more */
*p++ = '\0';
else
p = (char *)0;
ctr = (int)strtol(optarg, &op, 10);
if (*op != '\0') {
/* not a number, try name */
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (strcasecmp(optarg, EventDesc[ctr].name) == 0)
break;
}
}
if (*optarg == '\0' || ctr < 0 || ctr >= HWPERF_EVENTMAX) {
fprintf(stderr, "%s: Error: illegal counter name or number (%s)\n",
cmd, optarg);
exit(1);
}
evctr_set.hwp_evctrl[ctr].hwperf_spec = enable;
if (p == (char *)0)
break;
optarg = p;
}
}
int
evctr_global_status(FILE *f)
{
int ctr;
if (syssgi(SGI_EVENTCTR, HWPERF_GET_SYSEVCTRL, &evctr_args_get) < 0) {
if (errno == EINVAL)
fprintf(stderr, "%s: Warning: global counters not enabled\n", cmd);
else
fprintf(stderr, "%s: Warning: cannot get config for global counters: %s\n",
cmd, strerror(errno));
return 0;
}
fprintf(f, "The following global counters are enabled:\n");
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (evctr_args_get.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec)
fprintf(f, "[%2d] %-8s %s\n",
ctr, EventDesc[ctr].name, EventDesc[ctr].text);
}
return 1;
}
int
evctr_global_release(void)
{
if ((gen = syssgi(SGI_EVENTCTR, HWPERF_RELSYSCNTRS)) < 0) {
if (errno == EINVAL)
fprintf(stderr, "%s: Warning: global counters already disabled\n", cmd);
else
fprintf(stderr, "%s: Warning: cannot release global counters: %s\n",
cmd, strerror(errno));
return 0;
}
return 1;
}
int
evctr_global_set(void)
{
int ctr;
int active;
int enable;
/* get current setup ... */
if ((gen = syssgi(SGI_EVENTCTR, HWPERF_GET_SYSEVCTRL, &evctr_args_set)) < 0) {
/*
* on error or if global ctrs inactive,
* assume everything is disabled
*/
active = 0;
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++)
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 0;
}
else {
active = 1;
/* mark active ones as "1" */
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++)
if (evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec)
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 1;
}
/* turn some explicitly on/off ... */
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (evctr_set.hwp_evctrl[ctr].hwperf_spec == 0)
continue;
if (evctr_set.hwp_evctrl[ctr].hwperf_spec == 1) {
/* turned on with -e */
if (check_semantics(ctr, 1) == EVCTR_SEM_BAD) {
fprintf(stderr, "... this counter will not be enabled\n");
evctr_set.hwp_evctrl[ctr].hwperf_spec = 0;
continue;
}
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 1;
}
if (evctr_set.hwp_evctrl[ctr].hwperf_spec == -1) {
/*
* turned off with -d
* ... a bit trickier as we have to manage the equivalences
* [0,16] and [15,17]
*/
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 0;
if (cpucount.r12k == 0) {
if (ctr == 0)
evctr_args_set.hwp_evctrargs.hwp_evctrl[16].hwperf_spec = 0;
else if (ctr == 16)
evctr_args_set.hwp_evctrargs.hwp_evctrl[0].hwperf_spec = 0;
else if (ctr == 15)
evctr_args_set.hwp_evctrargs.hwp_evctrl[17].hwperf_spec = 0;
else if (ctr == 17)
evctr_args_set.hwp_evctrargs.hwp_evctrl[15].hwperf_spec = 0;
}
}
}
if (cpucount.r12k == 0)
remap(evctr_args_set.hwp_evctrargs.hwp_evctrl);
/*
* set up the controls ...
* if enabled thru here, we want no overflow thresholds,
* no user signals, and all possible modes!
*/
enable = 0;
evctr_args_set.hwp_ovflw_sig = 0;
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ ) {
evctr_args_set.hwp_ovflw_freq[ctr] = 0;
if (evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec == 1) {
enable++;
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_creg.hwp_mode =
HWPERF_CNTEN_U | HWPERF_CNTEN_K | HWPERF_CNTEN_E;
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_creg.hwp_ie = 1;
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_creg.hwp_ev =
ctr < HWPERF_CNT1BASE ? ctr : ctr - HWPERF_CNT1BASE;
}
else
evctr_args_set.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 0;
}
if (active) {
if (enable > 0) {
if ((gen = syssgi(SGI_EVENTCTR, HWPERF_SET_SYSEVCTRL, &evctr_args_set)) < 0) {
fprintf(stderr, "%s: Warning: cannot modify global counter state: %s\n",
cmd, strerror(errno));
return 0;
}
}
else
return evctr_global_release();
} else if (enable > 0) {
if ((gen = syssgi(SGI_EVENTCTR, HWPERF_ENSYSCNTRS, &evctr_args_set)) < 0) {
fprintf(stderr, "%s: Warning: cannot set global counters: %s\n",
cmd, strerror(errno));
return 0;
}
}
return 1;
}
#define S_INIT 0
#define S_ACTIVE 1
#define S_INACTIVE 2
static int state = S_INIT;
int
evctr_global_sample(int report)
{
int ctr;
int sts;
ActiveChanged = 0;
/* retrieve the counts */
if ((sts = syssgi(SGI_EVENTCTR, HWPERF_GET_SYSCNTRS, (void *)&Count)) < 0) {
if (state == S_INIT || state == S_ACTIVE) {
if (report) {
if (errno == EINVAL)
fprintf(stderr, "%s: Warning: global counters not enabled\n", cmd);
else
fprintf(stderr, "%s: Warning: cannot fetch global counters: %s\n",
cmd, strerror(errno));
}
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
Active[ctr] = 0;
Sem[ctr] = EVCTR_SEM_OK;
}
ActiveChanged = 1;
}
state = S_INACTIVE;
return 0;
}
if (state != S_ACTIVE || sts != gen) {
/*
* config changed, mark old results as invalid ...
* necessary because counters maybe re-set to zero
*/
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++)
OldCount[ctr] = -1;
state = S_ACTIVE; /* hope for the best */
/* get current setup ... */
if ((gen = syssgi(SGI_EVENTCTR, HWPERF_GET_SYSEVCTRL, &evctr_args_get)) < 0) {
if (report) {
if (errno == EINVAL)
fprintf(stderr, "%s: Warning: global counters not enabled\n", cmd);
else
fprintf(stderr, "%s: Warning: cannot get config for global counters: %s\n",
cmd, strerror(errno));
}
/* on error, assume everything is disabled */
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++)
evctr_args_get.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec = 0;
state = S_INACTIVE;
}
Use[0] = Use[1] = 0;
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (!evctr_args_get.hwp_evctrargs.hwp_evctrl[ctr].hwperf_spec) {
Active[ctr] = 0;
continue;
}
Sem[ctr] = check_semantics(ctr, report);
Active[ctr] = 1;
if (ctr < HWPERF_CNT1BASE)
Use[0]++;
else
Use[1]++;
}
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++) {
if (Active[ctr]) {
if (ctr < HWPERF_CNT1BASE)
Mux[ctr] = Use[0];
else
Mux[ctr] = Use[1];
}
else
Mux[ctr] = 0;
}
ActiveChanged = 1;
if (state == S_INACTIVE)
return 0;
}
return 1;
}
void
evctr_trustme(void)
{
trustme = 1;
}
+70
View File
@@ -0,0 +1,70 @@
#ifndef __EVCTR_UTIL_H__
#define __EVCTR_UTIL_H__
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/hwperftypes.h>
#include <sys/hwperfmacros.h>
#ifndef HWPERF_EVENTMAX
#define HWPERF_EVENTMAX 32
#endif
/*
* describe all of the events, their internal code, a short mneumonic
* and the full text of the counter's description
*/
typedef struct {
int ident;
char *name;
char *text;
} EventDesc_t;
extern EventDesc_t *EventDesc;
/*
* results of evctr_global_sample() ...
*/
extern int ActiveChanged;
extern int Active[HWPERF_EVENTMAX];
extern int Mux[HWPERF_EVENTMAX];
extern int Sem[HWPERF_EVENTMAX];
extern __uint64_t OldCount[HWPERF_EVENTMAX];
extern __uint64_t Count[HWPERF_EVENTMAX];
extern int Use[2]; /* mux count for each physical ctr */
/*
* CPU inventory by type
*/
typedef struct {
int r10k;
int r10k_rev2;
int r10k_rev3;
int r12k;
} cpucount_t;
extern cpucount_t cpucount;
/*
* for Sem[]
*/
#define EVCTR_SEM_BAD -1
#define EVCTR_SEM_OK 0
#define EVCTR_SEM_R10K_REV 1
#define EVCTR_SEM_R10K_R12K 2
/* global debug */
extern int evctr_debug;
/* semantic warnings control */
void evctr_init(char *);
void evctr_opt(char *, int);
void evctr_trustme(void);
int evctr_global_set(void);
int evctr_global_status(FILE *);
int evctr_global_sample(int);
int evctr_global_release(void);
#endif /* !__EVCTR_UTIL_H__ */
+96
View File
@@ -0,0 +1,96 @@
IRIX64 kudzu 6.2 with IMPACT 10000 06101031 IP28
1 195 MHZ IP28 Processor
CPU: MIPS R10000 Processor Chip Revision: 2.6
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
Data cache size: 32 Kbytes
Instruction cache size: 32 Kbytes
Secondary unified instruction/data cache size: 1 Mbyte
Main memory size: 96 Mbytes
/usr/etc/ecadmin
/usr/etc/ecstats
=== FP and cycles ===
ecadmin: Warning, global counters already disabled
195141960.20 [ 0] Cycles
2135087.80 [21] Floating point instructions graduated
2136089 FP ops per sec
2137352 FP ops per sec
195590391.50 [ 0] Cycles
2143458.50 [21] Floating point instructions graduated
2138259 FP ops per sec
195578247.20 [ 0] Cycles
2144682.70 [21] Floating point instructions graduated
13208 Terminated
13207 Terminated
=== 2$ miss ===
ecadmin: Warning, global counters already disabled
1047542.90 [26] Scache data misses
1046628 2 D-cache miss per sec
1047279 2 D-cache miss per sec
1050892.00 [26] Scache data misses
1047594 2 D-cache miss per sec
1050813.40 [26] Scache data misses
13216 Terminated
13215 Terminated
=== Store cond and FP ===
ecadmin: Warning, global counters already disabled
3108095.60 [ 4] Store conditionals issued
776955.00 [21] Floating point instructions graduated
789535 FP ops per sec
3158138 Store cond per sec
3169861.80 [ 4] Store conditionals issued
792470.60 [21] Floating point instructions graduated
790118 FP ops per sec
3160471 Store cond per sec
3168655.80 [ 4] Store conditionals issued
792168.30 [21] Floating point instructions graduated
789772 FP ops per sec
3159090 Store cond per sec
13224 Terminated
13223 Terminated
=== Multiple events ===
ecadmin: Warning, global counters already disabled
195360394.60* [ 0] Cycles
1812900.60* [ 4] Store conditionals issued
441144.40* [21] Floating point instructions graduated
536070.40* [26] Scache data misses
448546 FP ops per sec
448546 2 D-cache miss per sec
1794185 Store cond per sec
195741838.80* [ 0] Cycles
1795642.20* [ 4] Store conditionals issued
445234.20* [21] Floating point instructions graduated
586969.40* [26] Scache data misses
443227 FP ops per sec
443227 2 D-cache miss per sec
1772910 Store cond per sec
195356463.20* [ 0] Cycles
1829718.40* [ 4] Store conditionals issued
446622.40* [21] Floating point instructions graduated
562483.80* [26] Scache data misses
445653 FP ops per sec
445653 2 D-cache miss per sec
1782614 Store cond per sec
13232 Terminated
13231 Terminated
ecadmin: Warning, global counters already disabled
+90
View File
@@ -0,0 +1,90 @@
IRIX64 snort 6.5 05190003 IP27
CPU: MIPS R10000 Processor Chip Revision: 2.6
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
Processor 0: 180 MHZ IP27
Processor 1: 180 MHZ IP27
Processor 2: 180 MHZ IP27
Processor 3: 180 MHZ IP27
Processor 4: 180 MHZ IP27
Processor 5: 180 MHZ IP27
Processor 6: 180 MHZ IP27
Processor 7: 180 MHZ IP27
Main memory size: 256 Mbytes
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
Secondary unified instruction/data cache size: 1 Mbyte
/usr/etc/ecadmin
/usr/etc/ecstats
=== FP and cycles ===
1968272 FP ops per sec
1503014102.40 [ 0] Cycles
1971391.20 [21] Floating point instructions graduated
1968275 FP ops per sec
1502915389.50 [ 0] Cycles
1972294.10 [21] Floating point instructions graduated
1968532 FP ops per sec
1502795703.90 [ 0] Cycles
1972257.00 [21] Floating point instructions graduated
=== 2$ miss ===
1138253 2 D-cache miss per sec
1983003.90 [26] Scache data misses
1139504 2 D-cache miss per sec
1985282.50 [26] Scache data misses
1140833 2 D-cache miss per sec
2005387.00 [26] Scache data misses
=== Store cond and FP ===
3882412.30 [ 4] Store conditionals issued
748840.20 [21] Floating point instructions graduated
759042 FP ops per sec
3036169 Store cond per sec
3937066.10 [ 4] Store conditionals issued
760706.00 [21] Floating point instructions graduated
759198 FP ops per sec
3036792 Store cond per sec
3936612.70 [ 4] Store conditionals issued
760421.90 [21] Floating point instructions graduated
758974 FP ops per sec
3035896 Store cond per sec
=== Multiple events ===
1502294968.60* [ 0] Cycles
2420939.00* [ 4] Store conditionals issued
456541.40* [21] Floating point instructions graduated
1424739.40* [26] Scache data misses
463369 FP ops per sec
463369 2 D-cache miss per sec
1853474 Store cond per sec
1502310330.20* [ 0] Cycles
2452896.20* [ 4] Store conditionals issued
461637.40* [21] Floating point instructions graduated
1445403.80* [26] Scache data misses
461889 FP ops per sec
461889 2 D-cache miss per sec
1847557 Store cond per sec
1502310541.60* [ 0] Cycles
2632982.00* [ 4] Store conditionals issued
497378.80* [21] Floating point instructions graduated
1640391.80* [26] Scache data misses
496651 FP ops per sec
496651 2 D-cache miss per sec
1986603 Store cond per sec
+90
View File
@@ -0,0 +1,90 @@
IRIX64 snort 6.5 05190003 IP27
CPU: MIPS R10000 Processor Chip Revision: 2.6
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
Processor 0: 180 MHZ IP27
Processor 1: 180 MHZ IP27
Processor 2: 180 MHZ IP27
Processor 3: 180 MHZ IP27
Processor 4: 180 MHZ IP27
Processor 5: 180 MHZ IP27
Processor 6: 180 MHZ IP27
Processor 7: 180 MHZ IP27
Main memory size: 256 Mbytes
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
Secondary unified instruction/data cache size: 1 Mbyte
/tmp/ecadmin_6.2
/tmp/ecstats_6.2
=== FP and cycles ===
2133235 FP ops per sec
1502934909.50 [ 0] Cycles
2137719.10 [21] Floating point instructions graduated
2134509 FP ops per sec
1502901305.00 [ 0] Cycles
2138854.80 [21] Floating point instructions graduated
2132819 FP ops per sec
1502795579.30 [ 0] Cycles
2136842.10 [21] Floating point instructions graduated
=== 2$ miss ===
1031615 2 D-cache miss per sec
1916572.60 [26] Scache data misses
1000899 2 D-cache miss per sec
1851351.90 [26] Scache data misses
1048745 2 D-cache miss per sec
2109972.80 [26] Scache data misses
=== Store cond and FP ===
4201606.30 [ 4] Store conditionals issued
813363.90 [21] Floating point instructions graduated
823120 FP ops per sec
3292478 Store cond per sec
4259917.20 [ 4] Store conditionals issued
825111.60 [21] Floating point instructions graduated
823484 FP ops per sec
3293936 Store cond per sec
4264945.10 [ 4] Store conditionals issued
825116.10 [21] Floating point instructions graduated
823550 FP ops per sec
3294199 Store cond per sec
=== Multiple events ===
1502318452.80* [ 0] Cycles
2648625.20* [ 4] Store conditionals issued
503364.80* [21] Floating point instructions graduated
1538100.20* [26] Scache data misses
508272 FP ops per sec
508272 2 D-cache miss per sec
2033089 Store cond per sec
1502251377.80* [ 0] Cycles
2576248.20* [ 4] Store conditionals issued
488071.60* [21] Floating point instructions graduated
1494911.60* [26] Scache data misses
487303 FP ops per sec
487303 2 D-cache miss per sec
1949210 Store cond per sec
1502278722.80* [ 0] Cycles
2523383.00* [ 4] Store conditionals issued
477019.20* [21] Floating point instructions graduated
1466057.60* [26] Scache data misses
476519 FP ops per sec
476519 2 D-cache miss per sec
1906076 Store cond per sec
+84
View File
@@ -0,0 +1,84 @@
IRIX whirr 6.5-ALPHA-1275088120 6.5.2m 10220813 IP32
CPU: MIPS R10000 Processor Chip Revision: 2.6
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
1 175 MHZ IP32 Processor
Main memory size: 96 Mbytes
Secondary unified instruction/data cache size: 1 Mbyte on Processor 0
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
FLASH PROM version 4.10
/usr/etc/ecadmin
/usr/etc/ecstats
=== FP and cycles ===
1837235 FP ops per sec
175616313.20 [ 0] Cycles
1840385.60 [21] Floating point instructions graduated
1839764 FP ops per sec
175623605.10 [ 0] Cycles
1843510.50 [21] Floating point instructions graduated
1841449 FP ops per sec
175624755.20 [ 0] Cycles
1844866.60 [21] Floating point instructions graduated
=== 2$ miss ===
696634 2 D-cache miss per sec
700159.00 [26] Scache data misses
698198 2 D-cache miss per sec
700910.70 [26] Scache data misses
698309 2 D-cache miss per sec
700872.10 [26] Scache data misses
=== Store cond and FP ===
3637429.30 [ 4] Store conditionals issued
724258.50 [21] Floating point instructions graduated
728229 FP ops per sec
2912917 Store cond per sec
3659463.20 [ 4] Store conditionals issued
728945.40 [21] Floating point instructions graduated
727454 FP ops per sec
2909815 Store cond per sec
3666771.00 [ 4] Store conditionals issued
730733.80 [21] Floating point instructions graduated
729360 FP ops per sec
2917439 Store cond per sec
=== Multiple events ===
175642628.00* [ 0] Cycles
1708543.60* [ 4] Store conditionals issued
338130.00* [21] Floating point instructions graduated
454256.00* [26] Scache data misses
340628 FP ops per sec
340628 2 D-cache miss per sec
1362512 Store cond per sec
175573123.40* [ 0] Cycles
1723788.00* [ 4] Store conditionals issued
341147.20* [21] Floating point instructions graduated
458419.00* [26] Scache data misses
340775 FP ops per sec
340775 2 D-cache miss per sec
1363099 Store cond per sec
175572632.60* [ 0] Cycles
1723100.40* [ 4] Store conditionals issued
341532.20* [21] Floating point instructions graduated
457101.80* [26] Scache data misses
341200 FP ops per sec
341200 2 D-cache miss per sec
1364801 Store cond per sec
+84
View File
@@ -0,0 +1,84 @@
IRIX whirr 6.5-ALPHA-1275088120 6.5.2m 10220813 IP32
CPU: MIPS R10000 Processor Chip Revision: 2.6
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
1 175 MHZ IP32 Processor
Main memory size: 96 Mbytes
Secondary unified instruction/data cache size: 1 Mbyte on Processor 0
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
FLASH PROM version 4.10
/tmp/ecadmin_6.2
/tmp/ecstats_6.2
=== FP and cycles ===
1858492 FP ops per sec
175514592.10 [ 0] Cycles
1862573.10 [21] Floating point instructions graduated
1859655 FP ops per sec
175968380.60 [ 0] Cycles
1866981.10 [21] Floating point instructions graduated
1857051 FP ops per sec
175625751.20 [ 0] Cycles
1860458.10 [21] Floating point instructions graduated
=== 2$ miss ===
691960 2 D-cache miss per sec
698947.30 [26] Scache data misses
699247 2 D-cache miss per sec
702081.70 [26] Scache data misses
698793 2 D-cache miss per sec
701576.30 [26] Scache data misses
=== Store cond and FP ===
3544963.50 [ 4] Store conditionals issued
706340.90 [21] Floating point instructions graduated
710551 FP ops per sec
2842203 Store cond per sec
3575231.40 [ 4] Store conditionals issued
712371.60 [21] Floating point instructions graduated
711050 FP ops per sec
2844202 Store cond per sec
3579842.70 [ 4] Store conditionals issued
713353.70 [21] Floating point instructions graduated
711932 FP ops per sec
2847730 Store cond per sec
=== Multiple events ===
175567118.00* [ 0] Cycles
1698751.60* [ 4] Store conditionals issued
337350.00* [21] Floating point instructions graduated
452031.00* [26] Scache data misses
339240 FP ops per sec
339240 2 D-cache miss per sec
1356961 Store cond per sec
175551541.20* [ 0] Cycles
1712329.60* [ 4] Store conditionals issued
340716.40* [21] Floating point instructions graduated
454123.80* [26] Scache data misses
339584 FP ops per sec
339584 2 D-cache miss per sec
1358336 Store cond per sec
175557097.40* [ 0] Cycles
1715236.00* [ 4] Store conditionals issued
339710.40* [21] Floating point instructions graduated
454753.20* [26] Scache data misses
339308 FP ops per sec
339309 2 D-cache miss per sec
1357234 Store cond per sec
+81
View File
@@ -0,0 +1,81 @@
IRIX64 k2rack 6.5-mfl-80-SN0 6.5.2m 11050508 IP27
4 300 MHZ IP27 Processors
CPU: MIPS R12000 Processor Chip Revision: 2.1
FPU: MIPS R10010 Floating Point Chip Revision: 0.0
Main memory size: 1920 Mbytes
Instruction cache size: 32 Kbytes
Data cache size: 32 Kbytes
Secondary unified instruction/data cache size: 8 Mbytes
Secondary unified instruction/data cache size: 8 Mbytes
Secondary unified instruction/data cache size: 8 Mbytes
Secondary unified instruction/data cache size: 4 Mbytes
/tmp/ecadmin_6.5.3
/tmp/ecstats_6.5.3
=== FP alone ===
3118034 FP ops per sec
1202391122.00 [ 0] Cycles
2.90 [21] Graduated floating point instructions
3117908 FP ops per sec
1202375113.80 [ 0] Cycles
1.60 [21] Graduated floating point instructions
3116780 FP ops per sec
1202375581.40 [ 0] Cycles
1.10 [21] Graduated floating point instructions
=== 1 D-cache miss alone ===
2297265 1 D-cache miss per sec
35372.80 [25] Primary data cache misses
2296998 1 D-cache miss per sec
32471.00 [25] Primary data cache misses
2297373 1 D-cache miss per sec
31663.70 [25] Primary data cache misses
=== 2 D-cache miss alone ===
1737260 2 D-cache miss per sec
68.50 [26] Secondary data cache misses
1981037 2 D-cache miss per sec
56.40 [26] Secondary data cache misses
2089144 2 D-cache miss per sec
63.90 [26] Secondary data cache misses
=== all together ===
1344992 FP ops per sec
1344992 1 D-cache miss per sec
1344992 2 D-cache miss per sec
1201886543.80 [ 0] Cycles
1.80* [21] Graduated floating point instructions
46563.60* [25] Primary data cache misses
149.40* [26] Secondary data cache misses
1342977 FP ops per sec
1342976 1 D-cache miss per sec
1342976 2 D-cache miss per sec
1201938199.90 [ 0] Cycles
1.80* [21] Graduated floating point instructions
38015.70* [25] Primary data cache misses
128.10* [26] Secondary data cache misses
1338628 FP ops per sec
1338628 1 D-cache miss per sec
1338628 2 D-cache miss per sec
1201842939.50 [ 0] Cycles
1.80* [21] Graduated floating point instructions
36261.60* [25] Primary data cache misses
103.50* [26] Secondary data cache misses
+119
View File
@@ -0,0 +1,119 @@
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <ulocks.h>
static struct timeval then;
struct {
char *op;
int enable;
long ctr_last;
long ctr;
} control[] = {
{ "FP ops", 0, 0, 0 },
{ "1 D-cache miss (read)", 0, 0, 0 },
{ "2 D-cache miss (write)", 0, 0, 0 },
{ "Store cond", 0, 0, 0 },
};
static int ncontrol = sizeof(control) / sizeof(control[0]);
double x = 0.0;
char data[64 * 1024 * 1024 + 128];
char c;
int miss1 = 0;
int miss2 = 128;
int size2cache = 1024 * 1024;
int size1cache = 32 * 1024;
ulock_t mylock;
usptr_t *handle;
/*ARGSUSED*/
void
onalarm(int dummy)
{
struct timeval now;
double secs;
double rate;
int i;
gettimeofday(&now);
secs = now.tv_sec - then.tv_sec + (double)(now.tv_usec - then.tv_usec) / 1000000;
for (i = 0; i < ncontrol; i++) {
if (control[i].enable) {
rate = (control[i].ctr - control[i].ctr_last) / secs;
printf("%.0f %s per sec\n", rate, control[i].op);
control[i].ctr_last = control[i].ctr;
}
}
fflush(stdout);
then = now;
signal(SIGALRM, onalarm);
alarm(10);
}
main(int argc, char **argv)
{
int i;
int c;
double f = 1.25;
while ((c = getopt(argc, argv, "fdls")) != -1) {
switch (c) {
case 'f':
control[0].enable = 1;
break;
case 'd':
control[1].enable = 1;
break;
case 'l':
control[3].enable = 1;
unlink("arena");
handle = usinit("arena");
mylock = usnewlock(handle);
break;
case 's':
control[2].enable = 1;
break;
}
}
gettimeofday(&then);
signal(SIGALRM, onalarm);
alarm(10);
for ( ; ; ) {
for (i = 0; i < ncontrol; i++) {
if (control[i].enable) {
switch (i) {
case 0: /* FP */
x += f;
break;
case 1: /* 1 D-cache miss */
c = data[miss1];
miss1 += size1cache;
if (miss1 > size2cache) miss1 = 0;
break;
case 2: /* 2 D-cache miss, 8 Mb stride */
data[miss2] = 42;
miss2 += 8 * 1024 * 1024;
if (miss2 > sizeof(data)) miss2 = 128;
break;
case 3: /* Store conditional, 2 per call */
ussetlock(mylock);
usunsetlock(mylock);
control[i].ctr++;
control[i].ctr++;
control[i].ctr++;
break;
}
control[i].ctr++;
}
}
}
}
+147
View File
@@ -0,0 +1,147 @@
#!/bin/sh
PATH=.:/sbin:/usr/sbin:/usr/etc:/usr/bsd
export PATH
# admin_opts=$*
[ $# -eq 0 ] && set - 1 2 3 4 5 6 7 8 9 10
uname -aR
echo
hinv -c processor
hinv -c memory
echo
[ -z "$ecadmin" ] && ecadmin=ecadmin $admin_opts
[ -z "$ecstats" ] && ecstats=ecstats
csh -fc "which $ecadmin $ecstats" $admin_opts
tmp=/var/tmp/$$
trap "killall $ecstats; killall exer; $ecadmin -r; rm -f $tmp.*; exit" 0 1 2 3 15 $admin_opts
for arg
do
case $arg
in
1) echo
echo "=== [1] Cycles ==="
$ecadmin -r $admin_opts
$ecadmin -e cycles $admin_opts
$ecstats -s 3 10
$ecadmin -r $admin_opts
;;
2) echo
echo "=== [2] FP ==="
$ecadmin -r $admin_opts
$ecadmin -e fpg $admin_opts
exer -f >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
3) echo
echo "=== [3] FP and cycles ==="
$ecadmin -r $admin_opts
$ecadmin -e fpg,cycles $admin_opts
exer -f >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
4) echo
echo "=== [4] 2$ miss ==="
$ecadmin -r $admin_opts
$ecadmin -e '2$dmiss' $admin_opts
exer -s >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
5) echo
echo "=== [5] Quadword writes from 2$ ==="
$ecadmin -r $admin_opts
$ecadmin -e 'wb2$' $admin_opts
exer -s >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
6) echo
echo "=== [6] Quadword writes from 1$ ==="
$ecadmin -r $admin_opts
$ecadmin -e 'wb1$' $admin_opts
exer -s >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
7) echo
echo "=== [7] Store conditional issue (R10K) ==="
$ecadmin -r $admin_opts
$ecadmin -e scondi $admin_opts
exer -l >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
8) echo
echo "=== [8] Miss Handling Table Occupancy (MHTO) (R12K) ==="
$ecadmin -r $admin_opts
$ecadmin -e mhto $admin_opts
exer -l >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
9) echo
echo "=== [9] SCONDI (R10K) or MHTO (R12K) and FP ==="
$ecadmin -r $admin_opts
$ecadmin -e scondi $admin_opts
$ecadmin -e mhto $admin_opts
$ecadmin -e fpg $admin_opts
exer -fl >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
10) echo
echo "=== [10] Multiple events ==="
$ecadmin -r $admin_opts
$ecadmin -e cycles,fpg,'2$dmiss' $admin_opts
$ecadmin -e scondi $admin_opts
$ecadmin -e mhto $admin_opts
exer -fls >$tmp.out &
$ecstats -s 3 10
killall -TERM exer
wait
cat $tmp.out
$ecadmin -r $admin_opts
;;
esac
done
+63
View File
@@ -0,0 +1,63 @@
#!/bin/sh
for file
do
echo
echo "+++ $file +++"
echo " Event Expected Observed Error"
echo "------------ ------------ ------------ ---------"
nawk <$file '
BEGIN { op_seen["Cycles"] = 0 }
/Processor$/ { cycles = $1*$2*1000000 }
/^Processor / { cycles += $3*1000000 }
/^===/ { sect++; print sect,"1",$0; ec_seen = 0
for (i in op_seen) op_seen[i] = 0
}
/per sec/ { tag = $2 " " $2
op_seen[tag]++
if (op_seen[tag] == 2) print sect,"2",$0
}
NF == 0 && last_ec == 1 { ec_seen++ }
{ last_ec = 0 }
/\]/ { last_ec = 1
if (ec_seen == 1) print sect,"3",$0
}
END { print "1 2 ",cycles," Cycles per sec" }' \
| sort \
| ( sed -e 's/^[0-9][0-9]* [0-9][0-9]* //'; echo "===" ) \
| nawk '
BEGIN { xpect["2D$ miss"] = -1; xpect["Cycles"] = -1; ec["Cycles"] = -1 }
/^===/ { first = 1
for (i in xpect) {
if (xpect[i] != -1 && ec[i] != -1) {
if (i == "1D$ miss" && xpect["2D$ miss"] != -1)
xpect[i] += xpect["2D$ miss"]
printf "%12s %12d %12d %8.1f%%",i,xpect[i],ec[i],100*(ec[i]-xpect[i])/xpect[i]
if (first) {
printf " %s",title
first = 0
}
print ""
}
}
for (i in xpect) {
if (i != "Cycles")
xpect[i] = -1
ec[i] = -1
}
title = "==="
for (i = 2; i <= NF-1; i++)
title = title " " $i
}
/Cycles per/ { xpect["Cycles"] = $1; next }
/\] Cycles/ { ec["Cycles"] = $1; next }
/FP ops per/ { xpect["FP grad"] = $1; next }
/\] Floating/ { ec["FP grad"] = $1; next }
/1 D-cache m/ { xpect["1D$ miss"] = $1; next }
/\] Pcache d/ { ec["1D$ miss"] = $1; next }
/re cond per/ { xpect["Store cond"] = $1; next }
/4\] Store con/ { ec["Store cond"] = $1; next }
/2 D-cache m/ { xpect["2D$ miss"] = $1; next }
/\] Scache d/ { ec["2D$ miss"] = $1; next }'
done
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
#ident "$Id: report.c,v 1.3 1998/12/16 23:03:45 kenmcd Exp $"
#include <stdio.h>
#include "evctr_util.h"
void
report(int fflag, int rflag, int interval)
{
int ctr;
int done;
if (evctr_debug) {
printf("Counters:");
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ )
printf(" %llu", Count[ctr]);
putchar('\n');
}
for (ctr = 0; ctr < HWPERF_EVENTMAX; ctr++ ) {
if (Active[ctr]) {
done = 0;
if (evctr_debug > 1)
printf("new=%llu - old=%llu x mux=%d / interval=%d\n",
Count[ctr], OldCount[ctr], Mux[ctr], interval);
if (rflag) {
if (OldCount[ctr] != -1) {
printf("%18.2f", ((double)((Count[ctr] - OldCount[ctr]) * Mux[ctr])) / interval);
done = 1;
}
}
else {
printf("%18llu", Count[ctr] * Mux[ctr]);
done = 1;
}
if (done) {
putchar(' ');
if (Sem[ctr] != EVCTR_SEM_OK)
putchar('?');
else if (Mux[ctr] > 1)
putchar('*');
else
putchar(' ');
}
OldCount[ctr] = Count[ctr];
}
else if (fflag)
printf("%18s ", "<inactive>");
if ((Active[ctr] && done) || fflag)
printf(" [%2d] %s\n", ctr, EventDesc[ctr].text);
}
putchar('\n');
}