1d95b3509SRandall Stewart /*-
252467047SWarner Losh * Copyright (c) 2014-2015 Netflix, Inc.
3d95b3509SRandall Stewart *
4d95b3509SRandall Stewart * Redistribution and use in source and binary forms, with or without
5d95b3509SRandall Stewart * modification, are permitted provided that the following conditions
6d95b3509SRandall Stewart * are met:
7d95b3509SRandall Stewart * 1. Redistributions of source code must retain the above copyright
8d95b3509SRandall Stewart * notice, this list of conditions and the following disclaimer,
9d95b3509SRandall Stewart * in this position and unchanged.
10d95b3509SRandall Stewart * 2. Redistributions in binary form must reproduce the above copyright
11d95b3509SRandall Stewart * notice, this list of conditions and the following disclaimer in the
12d95b3509SRandall Stewart * documentation and/or other materials provided with the distribution.
13d95b3509SRandall Stewart * 3. The name of the author may not be used to endorse or promote products
14d95b3509SRandall Stewart * derived from this software without specific prior written permission
15d95b3509SRandall Stewart *
16d95b3509SRandall Stewart * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17d95b3509SRandall Stewart * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18d95b3509SRandall Stewart * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19d95b3509SRandall Stewart * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20d95b3509SRandall Stewart * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21d95b3509SRandall Stewart * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22d95b3509SRandall Stewart * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23d95b3509SRandall Stewart * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24d95b3509SRandall Stewart * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25d95b3509SRandall Stewart * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26d95b3509SRandall Stewart */
27d95b3509SRandall Stewart #include <sys/types.h>
28d95b3509SRandall Stewart #include <stdio.h>
29d95b3509SRandall Stewart #include <stdlib.h>
30d95b3509SRandall Stewart #include <unistd.h>
31d95b3509SRandall Stewart #include <string.h>
32d95b3509SRandall Stewart #include <strings.h>
33d95b3509SRandall Stewart #include <sys/errno.h>
34d95b3509SRandall Stewart #include <signal.h>
35d95b3509SRandall Stewart #include <sys/wait.h>
36d95b3509SRandall Stewart #include <getopt.h>
37d95b3509SRandall Stewart #include "eval_expr.h"
38eef0660aSRandall Stewart static int max_pmc_counters = 1;
39eef0660aSRandall Stewart static int run_all = 0;
40eef0660aSRandall Stewart
41d95b3509SRandall Stewart #define MAX_COUNTER_SLOTS 1024
42d95b3509SRandall Stewart #define MAX_NLEN 64
43d95b3509SRandall Stewart #define MAX_CPU 64
44d95b3509SRandall Stewart static int verbose = 0;
45d95b3509SRandall Stewart
46d95b3509SRandall Stewart extern char **environ;
47d95b3509SRandall Stewart extern struct expression *master_exp;
48d95b3509SRandall Stewart struct expression *master_exp=NULL;
49d95b3509SRandall Stewart
50d95b3509SRandall Stewart #define PMC_INITIAL_ALLOC 512
51d95b3509SRandall Stewart extern char **valid_pmcs;
52d95b3509SRandall Stewart char **valid_pmcs = NULL;
53d95b3509SRandall Stewart extern int valid_pmc_cnt;
54d95b3509SRandall Stewart int valid_pmc_cnt=0;
55d95b3509SRandall Stewart extern int pmc_allocated_cnt;
56d95b3509SRandall Stewart int pmc_allocated_cnt=0;
57d95b3509SRandall Stewart
58d95b3509SRandall Stewart /*
59d95b3509SRandall Stewart * The following two varients on popen and pclose with
60d95b3509SRandall Stewart * the cavet that they get you the PID so that you
61d95b3509SRandall Stewart * can supply it to pclose so it can send a SIGTERM
62d95b3509SRandall Stewart * to the process.
63d95b3509SRandall Stewart */
64d95b3509SRandall Stewart static FILE *
my_popen(const char * command,const char * dir,pid_t * p_pid)65d95b3509SRandall Stewart my_popen(const char *command, const char *dir, pid_t *p_pid)
66d95b3509SRandall Stewart {
67d95b3509SRandall Stewart FILE *io_out, *io_in;
68d95b3509SRandall Stewart int pdesin[2], pdesout[2];
69d95b3509SRandall Stewart char *argv[4];
70d95b3509SRandall Stewart pid_t pid;
71d95b3509SRandall Stewart char cmd[4];
72d95b3509SRandall Stewart char cmd2[1024];
73d95b3509SRandall Stewart char arg1[4];
74d95b3509SRandall Stewart
75d95b3509SRandall Stewart if ((strcmp(dir, "r") != 0) &&
76d95b3509SRandall Stewart (strcmp(dir, "w") != 0)) {
77d95b3509SRandall Stewart errno = EINVAL;
78d95b3509SRandall Stewart return(NULL);
79d95b3509SRandall Stewart }
80d95b3509SRandall Stewart if (pipe(pdesin) < 0)
81d95b3509SRandall Stewart return (NULL);
82d95b3509SRandall Stewart
83d95b3509SRandall Stewart if (pipe(pdesout) < 0) {
84d95b3509SRandall Stewart (void)close(pdesin[0]);
85d95b3509SRandall Stewart (void)close(pdesin[1]);
86d95b3509SRandall Stewart return (NULL);
87d95b3509SRandall Stewart }
88d95b3509SRandall Stewart strcpy(cmd, "sh");
89d95b3509SRandall Stewart strcpy(arg1, "-c");
90d95b3509SRandall Stewart strcpy(cmd2, command);
91d95b3509SRandall Stewart argv[0] = cmd;
92d95b3509SRandall Stewart argv[1] = arg1;
93d95b3509SRandall Stewart argv[2] = cmd2;
94d95b3509SRandall Stewart argv[3] = NULL;
95d95b3509SRandall Stewart
96d95b3509SRandall Stewart switch (pid = fork()) {
97d95b3509SRandall Stewart case -1: /* Error. */
98d95b3509SRandall Stewart (void)close(pdesin[0]);
99d95b3509SRandall Stewart (void)close(pdesin[1]);
100d95b3509SRandall Stewart (void)close(pdesout[0]);
101d95b3509SRandall Stewart (void)close(pdesout[1]);
102d95b3509SRandall Stewart return (NULL);
103d95b3509SRandall Stewart /* NOTREACHED */
104d95b3509SRandall Stewart case 0: /* Child. */
105d95b3509SRandall Stewart /* Close out un-used sides */
106d95b3509SRandall Stewart (void)close(pdesin[1]);
107d95b3509SRandall Stewart (void)close(pdesout[0]);
108d95b3509SRandall Stewart /* Now prepare the stdin of the process */
109d95b3509SRandall Stewart close(0);
110d95b3509SRandall Stewart (void)dup(pdesin[0]);
111d95b3509SRandall Stewart (void)close(pdesin[0]);
112d95b3509SRandall Stewart /* Now prepare the stdout of the process */
113d95b3509SRandall Stewart close(1);
114d95b3509SRandall Stewart (void)dup(pdesout[1]);
115d95b3509SRandall Stewart /* And lets do stderr just in case */
116d95b3509SRandall Stewart close(2);
117d95b3509SRandall Stewart (void)dup(pdesout[1]);
118d95b3509SRandall Stewart (void)close(pdesout[1]);
119d95b3509SRandall Stewart /* Now run it */
120d95b3509SRandall Stewart execve("/bin/sh", argv, environ);
121d95b3509SRandall Stewart exit(127);
122d95b3509SRandall Stewart /* NOTREACHED */
123d95b3509SRandall Stewart }
124d95b3509SRandall Stewart /* Parent; assume fdopen can't fail. */
125d95b3509SRandall Stewart /* Store the pid */
126d95b3509SRandall Stewart *p_pid = pid;
127d95b3509SRandall Stewart if (strcmp(dir, "r") != 0) {
128d95b3509SRandall Stewart io_out = fdopen(pdesin[1], "w");
129d95b3509SRandall Stewart (void)close(pdesin[0]);
130d95b3509SRandall Stewart (void)close(pdesout[0]);
131d95b3509SRandall Stewart (void)close(pdesout[1]);
132d95b3509SRandall Stewart return(io_out);
133d95b3509SRandall Stewart } else {
134d95b3509SRandall Stewart /* Prepare the input stream */
135d95b3509SRandall Stewart io_in = fdopen(pdesout[0], "r");
136d95b3509SRandall Stewart (void)close(pdesout[1]);
137d95b3509SRandall Stewart (void)close(pdesin[0]);
138d95b3509SRandall Stewart (void)close(pdesin[1]);
139d95b3509SRandall Stewart return (io_in);
140d95b3509SRandall Stewart }
141d95b3509SRandall Stewart }
142d95b3509SRandall Stewart
143d95b3509SRandall Stewart /*
144d95b3509SRandall Stewart * pclose --
145d95b3509SRandall Stewart * Pclose returns -1 if stream is not associated with a `popened' command,
146d95b3509SRandall Stewart * if already `pclosed', or waitpid returns an error.
147d95b3509SRandall Stewart */
148d95b3509SRandall Stewart static void
my_pclose(FILE * io,pid_t the_pid)149d95b3509SRandall Stewart my_pclose(FILE *io, pid_t the_pid)
150d95b3509SRandall Stewart {
151d95b3509SRandall Stewart int pstat;
152d95b3509SRandall Stewart pid_t pid;
153d95b3509SRandall Stewart
154d95b3509SRandall Stewart /*
155d95b3509SRandall Stewart * Find the appropriate file pointer and remove it from the list.
156d95b3509SRandall Stewart */
157d95b3509SRandall Stewart (void)fclose(io);
158d95b3509SRandall Stewart /* Die if you are not dead! */
159d95b3509SRandall Stewart kill(the_pid, SIGTERM);
160d95b3509SRandall Stewart do {
161d95b3509SRandall Stewart pid = wait4(the_pid, &pstat, 0, (struct rusage *)0);
162d95b3509SRandall Stewart } while (pid == -1 && errno == EINTR);
163d95b3509SRandall Stewart }
164d95b3509SRandall Stewart
165d95b3509SRandall Stewart struct counters {
166d95b3509SRandall Stewart struct counters *next_cpu;
167d95b3509SRandall Stewart char counter_name[MAX_NLEN]; /* Name of counter */
168d95b3509SRandall Stewart int cpu; /* CPU we are on */
169d95b3509SRandall Stewart int pos; /* Index we are filling to. */
170d95b3509SRandall Stewart uint64_t vals[MAX_COUNTER_SLOTS]; /* Last 64 entries */
171d95b3509SRandall Stewart uint64_t sum; /* Summary of entries */
172d95b3509SRandall Stewart };
173d95b3509SRandall Stewart
174d95b3509SRandall Stewart extern struct counters *glob_cpu[MAX_CPU];
175d95b3509SRandall Stewart struct counters *glob_cpu[MAX_CPU];
176d95b3509SRandall Stewart
177d95b3509SRandall Stewart extern struct counters *cnts;
178d95b3509SRandall Stewart struct counters *cnts=NULL;
179d95b3509SRandall Stewart
180d95b3509SRandall Stewart extern int ncnts;
181d95b3509SRandall Stewart int ncnts=0;
182d95b3509SRandall Stewart
183d95b3509SRandall Stewart extern int (*expression)(struct counters *, int);
184d95b3509SRandall Stewart int (*expression)(struct counters *, int);
185d95b3509SRandall Stewart
186d95b3509SRandall Stewart static const char *threshold=NULL;
187d95b3509SRandall Stewart static const char *command;
188d95b3509SRandall Stewart
189d95b3509SRandall Stewart struct cpu_entry {
190d95b3509SRandall Stewart const char *name;
191d95b3509SRandall Stewart const char *thresh;
192d95b3509SRandall Stewart const char *command;
193d95b3509SRandall Stewart int (*func)(struct counters *, int);
194eef0660aSRandall Stewart int counters_required;
195d95b3509SRandall Stewart };
196d95b3509SRandall Stewart
197d95b3509SRandall Stewart struct cpu_type {
198d95b3509SRandall Stewart char cputype[32];
199d95b3509SRandall Stewart int number;
200d95b3509SRandall Stewart struct cpu_entry *ents;
201d95b3509SRandall Stewart void (*explain)(const char *name);
202d95b3509SRandall Stewart };
203d95b3509SRandall Stewart extern struct cpu_type the_cpu;
204d95b3509SRandall Stewart struct cpu_type the_cpu;
205d95b3509SRandall Stewart
206d95b3509SRandall Stewart static void
explain_name_sb(const char * name)207d95b3509SRandall Stewart explain_name_sb(const char *name)
208d95b3509SRandall Stewart {
209d95b3509SRandall Stewart const char *mythresh;
210d95b3509SRandall Stewart if (strcmp(name, "allocstall1") == 0) {
211d95b3509SRandall Stewart printf("Examine PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW / CPU_CLK_UNHALTED.THREAD_P\n");
212d95b3509SRandall Stewart mythresh = "thresh > .05";
213d95b3509SRandall Stewart } else if (strcmp(name, "allocstall2") == 0) {
214d95b3509SRandall Stewart printf("Examine PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P\n");
215d95b3509SRandall Stewart mythresh = "thresh > .05";
216d95b3509SRandall Stewart } else if (strcmp(name, "br_miss") == 0) {
217d95b3509SRandall Stewart printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P\n");
218d95b3509SRandall Stewart mythresh = "thresh >= .2";
219d95b3509SRandall Stewart } else if (strcmp(name, "splitload") == 0) {
220eef0660aSRandall Stewart printf("Examine MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
221d95b3509SRandall Stewart mythresh = "thresh >= .1";
222d95b3509SRandall Stewart } else if (strcmp(name, "splitstore") == 0) {
223eef0660aSRandall Stewart printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
224d95b3509SRandall Stewart mythresh = "thresh >= .01";
225d95b3509SRandall Stewart } else if (strcmp(name, "contested") == 0) {
226d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n");
227d95b3509SRandall Stewart mythresh = "thresh >= .05";
228d95b3509SRandall Stewart } else if (strcmp(name, "blockstorefwd") == 0) {
229d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
230d95b3509SRandall Stewart mythresh = "thresh >= .05";
231d95b3509SRandall Stewart } else if (strcmp(name, "cache2") == 0) {
232d95b3509SRandall Stewart printf("Examine ((MEM_LOAD_RETIRED.L3_HIT * 26) + \n");
233d95b3509SRandall Stewart printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) + \n");
234d95b3509SRandall Stewart printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P\n");
235d95b3509SRandall Stewart printf("**Note we have it labeled MEM_LOAD_UOPS_RETIRED.LLC_HIT not MEM_LOAD_RETIRED.L3_HIT\n");
236d95b3509SRandall Stewart mythresh = "thresh >= .2";
237d95b3509SRandall Stewart } else if (strcmp(name, "cache1") == 0) {
238d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P\n");
239d95b3509SRandall Stewart mythresh = "thresh >= .2";
240d95b3509SRandall Stewart } else if (strcmp(name, "dtlbmissload") == 0) {
241d95b3509SRandall Stewart printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n");
242d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
243d95b3509SRandall Stewart mythresh = "thresh >= .1";
244d95b3509SRandall Stewart } else if (strcmp(name, "frontendstall") == 0) {
245d95b3509SRandall Stewart printf("Examine IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4)\n");
246d95b3509SRandall Stewart mythresh = "thresh >= .15";
247d95b3509SRandall Stewart } else if (strcmp(name, "clears") == 0) {
248d95b3509SRandall Stewart printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n");
249d95b3509SRandall Stewart printf(" MACHINE_CLEARS.SMC + \n");
250d95b3509SRandall Stewart printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n");
251d95b3509SRandall Stewart mythresh = "thresh >= .02";
252d95b3509SRandall Stewart } else if (strcmp(name, "microassist") == 0) {
253d95b3509SRandall Stewart printf("Examine IDQ.MS_CYCLES / (CPU_CLK_UNHALTED.THREAD_P * 4)\n");
254d95b3509SRandall Stewart printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n");
255d95b3509SRandall Stewart mythresh = "thresh >= .05";
256d95b3509SRandall Stewart } else if (strcmp(name, "aliasing_4k") == 0) {
257d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
258d95b3509SRandall Stewart mythresh = "thresh >= .1";
259d95b3509SRandall Stewart } else if (strcmp(name, "fpassist") == 0) {
260d95b3509SRandall Stewart printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n");
261d95b3509SRandall Stewart mythresh = "look for a excessive value";
262d95b3509SRandall Stewart } else if (strcmp(name, "otherassistavx") == 0) {
263d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
264d95b3509SRandall Stewart mythresh = "look for a excessive value";
265d95b3509SRandall Stewart } else if (strcmp(name, "otherassistsse") == 0) {
266d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
267d95b3509SRandall Stewart mythresh = "look for a excessive value";
268d95b3509SRandall Stewart } else if (strcmp(name, "eff1") == 0) {
269d95b3509SRandall Stewart printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n");
270d95b3509SRandall Stewart mythresh = "thresh < .9";
271d95b3509SRandall Stewart } else if (strcmp(name, "eff2") == 0) {
272d95b3509SRandall Stewart printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n");
273d95b3509SRandall Stewart mythresh = "thresh > 1.0";
274d95b3509SRandall Stewart } else if (strcmp(name, "dtlbmissstore") == 0) {
275d95b3509SRandall Stewart printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n");
276d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
277d95b3509SRandall Stewart mythresh = "thresh >= .05";
278d95b3509SRandall Stewart } else {
279d95b3509SRandall Stewart printf("Unknown name:%s\n", name);
280d95b3509SRandall Stewart mythresh = "unknown entry";
281d95b3509SRandall Stewart }
282d95b3509SRandall Stewart printf("If the value printed is %s we may have the ability to improve performance\n", mythresh);
283d95b3509SRandall Stewart }
284d95b3509SRandall Stewart
285d95b3509SRandall Stewart static void
explain_name_ib(const char * name)286d95b3509SRandall Stewart explain_name_ib(const char *name)
287d95b3509SRandall Stewart {
288d95b3509SRandall Stewart const char *mythresh;
289d95b3509SRandall Stewart if (strcmp(name, "br_miss") == 0) {
290d95b3509SRandall Stewart printf("Examine ((BR_MISP_RETIRED.ALL_BRANCHES /(BR_MISP_RETIRED.ALL_BRANCHES +\n");
291d95b3509SRandall Stewart printf(" MACHINE_CLEAR.COUNT) * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES)\n");
292d95b3509SRandall Stewart printf("/ (4 * CPU_CLK_UNHALTED.THREAD))))\n");
293d95b3509SRandall Stewart mythresh = "thresh >= .2";
294d95b3509SRandall Stewart } else if (strcmp(name, "eff1") == 0) {
295d95b3509SRandall Stewart printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n");
296d95b3509SRandall Stewart mythresh = "thresh < .9";
297d95b3509SRandall Stewart } else if (strcmp(name, "eff2") == 0) {
298d95b3509SRandall Stewart printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n");
299d95b3509SRandall Stewart mythresh = "thresh > 1.0";
300d95b3509SRandall Stewart } else if (strcmp(name, "cache1") == 0) {
301d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n");
302d95b3509SRandall Stewart mythresh = "thresh >= .2";
303d95b3509SRandall Stewart } else if (strcmp(name, "cache2") == 0) {
304d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P\n");
305d95b3509SRandall Stewart mythresh = "thresh >= .2";
306d95b3509SRandall Stewart } else if (strcmp(name, "itlbmiss") == 0) {
307d95b3509SRandall Stewart printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n");
308d95b3509SRandall Stewart mythresh = "thresh > .05";
309d95b3509SRandall Stewart } else if (strcmp(name, "icachemiss") == 0) {
310d95b3509SRandall Stewart printf("Examine (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION)/ CPU_CLK_UNHALTED.THREAD_P\n");
311d95b3509SRandall Stewart mythresh = "thresh > .05";
312d95b3509SRandall Stewart } else if (strcmp(name, "lcpstall") == 0) {
313d95b3509SRandall Stewart printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n");
314d95b3509SRandall Stewart mythresh = "thresh > .05";
315d95b3509SRandall Stewart } else if (strcmp(name, "datashare") == 0) {
316d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/CPU_CLK_UNHALTED.THREAD_P\n");
317d95b3509SRandall Stewart mythresh = "thresh > .05";
318d95b3509SRandall Stewart } else if (strcmp(name, "blockstorefwd") == 0) {
319d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
320d95b3509SRandall Stewart mythresh = "thresh >= .05";
321d95b3509SRandall Stewart } else if (strcmp(name, "splitload") == 0) {
322d95b3509SRandall Stewart printf("Examine ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) *\n");
323d95b3509SRandall Stewart printf(" LD_BLOCKS.NO_SR)/CPU_CLK_UNHALTED.THREAD_P\n");
324d95b3509SRandall Stewart mythresh = "thresh >= .1";
325d95b3509SRandall Stewart } else if (strcmp(name, "splitstore") == 0) {
326eef0660aSRandall Stewart printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
327d95b3509SRandall Stewart mythresh = "thresh >= .01";
328d95b3509SRandall Stewart } else if (strcmp(name, "aliasing_4k") == 0) {
329d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
330d95b3509SRandall Stewart mythresh = "thresh >= .1";
331d95b3509SRandall Stewart } else if (strcmp(name, "dtlbmissload") == 0) {
332d95b3509SRandall Stewart printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n");
333d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
334d95b3509SRandall Stewart mythresh = "thresh >= .1";
335d95b3509SRandall Stewart } else if (strcmp(name, "dtlbmissstore") == 0) {
336d95b3509SRandall Stewart printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n");
337d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
338d95b3509SRandall Stewart mythresh = "thresh >= .05";
339d95b3509SRandall Stewart } else if (strcmp(name, "contested") == 0) {
340d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n");
341d95b3509SRandall Stewart mythresh = "thresh >= .05";
342d95b3509SRandall Stewart } else if (strcmp(name, "clears") == 0) {
343d95b3509SRandall Stewart printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n");
344d95b3509SRandall Stewart printf(" MACHINE_CLEARS.SMC + \n");
345d95b3509SRandall Stewart printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n");
346d95b3509SRandall Stewart mythresh = "thresh >= .02";
347d95b3509SRandall Stewart } else if (strcmp(name, "microassist") == 0) {
348d95b3509SRandall Stewart printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n");
349d95b3509SRandall Stewart printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n");
350d95b3509SRandall Stewart mythresh = "thresh >= .05";
351d95b3509SRandall Stewart } else if (strcmp(name, "fpassist") == 0) {
352d95b3509SRandall Stewart printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n");
353d95b3509SRandall Stewart mythresh = "look for a excessive value";
354d95b3509SRandall Stewart } else if (strcmp(name, "otherassistavx") == 0) {
355d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
356d95b3509SRandall Stewart mythresh = "look for a excessive value";
357d95b3509SRandall Stewart } else if (strcmp(name, "otherassistsse") == 0) {
358d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
359d95b3509SRandall Stewart mythresh = "look for a excessive value";
360d95b3509SRandall Stewart } else {
361d95b3509SRandall Stewart printf("Unknown name:%s\n", name);
362d95b3509SRandall Stewart mythresh = "unknown entry";
363d95b3509SRandall Stewart }
364d95b3509SRandall Stewart printf("If the value printed is %s we may have the ability to improve performance\n", mythresh);
365d95b3509SRandall Stewart }
366d95b3509SRandall Stewart
367d95b3509SRandall Stewart
368d95b3509SRandall Stewart static void
explain_name_has(const char * name)369d95b3509SRandall Stewart explain_name_has(const char *name)
370d95b3509SRandall Stewart {
371d95b3509SRandall Stewart const char *mythresh;
372d95b3509SRandall Stewart if (strcmp(name, "eff1") == 0) {
373d95b3509SRandall Stewart printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n");
374d95b3509SRandall Stewart mythresh = "thresh < .75";
375d95b3509SRandall Stewart } else if (strcmp(name, "eff2") == 0) {
376d95b3509SRandall Stewart printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n");
377d95b3509SRandall Stewart mythresh = "thresh > 1.0";
378d95b3509SRandall Stewart } else if (strcmp(name, "itlbmiss") == 0) {
379d95b3509SRandall Stewart printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n");
380d95b3509SRandall Stewart mythresh = "thresh > .05";
381d95b3509SRandall Stewart } else if (strcmp(name, "icachemiss") == 0) {
382d95b3509SRandall Stewart printf("Examine (36 * ICACHE.MISSES)/ CPU_CLK_UNHALTED.THREAD_P\n");
383d95b3509SRandall Stewart mythresh = "thresh > .05";
384d95b3509SRandall Stewart } else if (strcmp(name, "lcpstall") == 0) {
385d95b3509SRandall Stewart printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n");
386d95b3509SRandall Stewart mythresh = "thresh > .05";
387d95b3509SRandall Stewart } else if (strcmp(name, "cache1") == 0) {
388d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n");
389d95b3509SRandall Stewart mythresh = "thresh >= .2";
390d95b3509SRandall Stewart } else if (strcmp(name, "cache2") == 0) {
391d95b3509SRandall Stewart printf("Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \n");
392d95b3509SRandall Stewart printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) + \n");
393d95b3509SRandall Stewart printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84))\n");
394d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P\n");
395d95b3509SRandall Stewart mythresh = "thresh >= .2";
396d95b3509SRandall Stewart } else if (strcmp(name, "contested") == 0) {
397d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P\n");
398d95b3509SRandall Stewart mythresh = "thresh >= .05";
399d95b3509SRandall Stewart } else if (strcmp(name, "datashare") == 0) {
400d95b3509SRandall Stewart printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 72)/CPU_CLK_UNHALTED.THREAD_P\n");
401d95b3509SRandall Stewart mythresh = "thresh > .05";
402d95b3509SRandall Stewart } else if (strcmp(name, "blockstorefwd") == 0) {
403d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
404d95b3509SRandall Stewart mythresh = "thresh >= .05";
405d95b3509SRandall Stewart } else if (strcmp(name, "splitload") == 0) {
406eef0660aSRandall Stewart printf("Examine (MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
407d95b3509SRandall Stewart mythresh = "thresh >= .1";
408d95b3509SRandall Stewart } else if (strcmp(name, "splitstore") == 0) {
409eef0660aSRandall Stewart printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
410d95b3509SRandall Stewart mythresh = "thresh >= .01";
411d95b3509SRandall Stewart } else if (strcmp(name, "aliasing_4k") == 0) {
412d95b3509SRandall Stewart printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
413d95b3509SRandall Stewart mythresh = "thresh >= .1";
414d95b3509SRandall Stewart } else if (strcmp(name, "dtlbmissload") == 0) {
415d95b3509SRandall Stewart printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n");
416d95b3509SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
417d95b3509SRandall Stewart mythresh = "thresh >= .1";
418d95b3509SRandall Stewart } else if (strcmp(name, "br_miss") == 0) {
419d95b3509SRandall Stewart printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD\n");
420d95b3509SRandall Stewart mythresh = "thresh >= .2";
421d95b3509SRandall Stewart } else if (strcmp(name, "clears") == 0) {
422d95b3509SRandall Stewart printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n");
423d95b3509SRandall Stewart printf(" MACHINE_CLEARS.SMC + \n");
424d95b3509SRandall Stewart printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n");
425d95b3509SRandall Stewart mythresh = "thresh >= .02";
426d95b3509SRandall Stewart } else if (strcmp(name, "microassist") == 0) {
427d95b3509SRandall Stewart printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n");
428d95b3509SRandall Stewart printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n");
429d95b3509SRandall Stewart mythresh = "thresh >= .05";
430d95b3509SRandall Stewart } else if (strcmp(name, "fpassist") == 0) {
431d95b3509SRandall Stewart printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n");
432d95b3509SRandall Stewart mythresh = "look for a excessive value";
433d95b3509SRandall Stewart } else if (strcmp(name, "otherassistavx") == 0) {
434d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
435d95b3509SRandall Stewart mythresh = "look for a excessive value";
436d95b3509SRandall Stewart } else if (strcmp(name, "otherassistsse") == 0) {
437d95b3509SRandall Stewart printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
438d95b3509SRandall Stewart mythresh = "look for a excessive value";
439d95b3509SRandall Stewart } else {
440d95b3509SRandall Stewart printf("Unknown name:%s\n", name);
441d95b3509SRandall Stewart mythresh = "unknown entry";
442d95b3509SRandall Stewart }
443d95b3509SRandall Stewart printf("If the value printed is %s we may have the ability to improve performance\n", mythresh);
444d95b3509SRandall Stewart }
445d95b3509SRandall Stewart
446eef0660aSRandall Stewart
447eef0660aSRandall Stewart
448d95b3509SRandall Stewart static struct counters *
find_counter(struct counters * base,const char * name)449d95b3509SRandall Stewart find_counter(struct counters *base, const char *name)
450d95b3509SRandall Stewart {
451d95b3509SRandall Stewart struct counters *at;
452d95b3509SRandall Stewart int len;
453d95b3509SRandall Stewart
454d95b3509SRandall Stewart at = base;
455d95b3509SRandall Stewart len = strlen(name);
456d95b3509SRandall Stewart while(at) {
457d95b3509SRandall Stewart if (strncmp(at->counter_name, name, len) == 0) {
458d95b3509SRandall Stewart return(at);
459d95b3509SRandall Stewart }
460d95b3509SRandall Stewart at = at->next_cpu;
461d95b3509SRandall Stewart }
462d95b3509SRandall Stewart printf("Can't find counter %s\n", name);
463d95b3509SRandall Stewart printf("We have:\n");
464d95b3509SRandall Stewart at = base;
465d95b3509SRandall Stewart while(at) {
466d95b3509SRandall Stewart printf("- %s\n", at->counter_name);
467d95b3509SRandall Stewart at = at->next_cpu;
468d95b3509SRandall Stewart }
469d95b3509SRandall Stewart exit(-1);
470d95b3509SRandall Stewart }
471d95b3509SRandall Stewart
472d95b3509SRandall Stewart static int
allocstall1(struct counters * cpu,int pos)473d95b3509SRandall Stewart allocstall1(struct counters *cpu, int pos)
474d95b3509SRandall Stewart {
475d95b3509SRandall Stewart /* 1 - PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW/CPU_CLK_UNHALTED.THREAD_P (thresh > .05)*/
476d95b3509SRandall Stewart int ret;
477d95b3509SRandall Stewart struct counters *partial;
478d95b3509SRandall Stewart struct counters *unhalt;
479d95b3509SRandall Stewart double un, par, res;
480d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
481d95b3509SRandall Stewart partial = find_counter(cpu, "PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW");
482d95b3509SRandall Stewart if (pos != -1) {
483d95b3509SRandall Stewart par = partial->vals[pos] * 1.0;
484d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
485d95b3509SRandall Stewart } else {
486d95b3509SRandall Stewart par = partial->sum * 1.0;
487d95b3509SRandall Stewart un = unhalt->sum * 1.0;
488d95b3509SRandall Stewart }
489d95b3509SRandall Stewart res = par/un;
490d95b3509SRandall Stewart ret = printf("%1.3f", res);
491d95b3509SRandall Stewart return(ret);
492d95b3509SRandall Stewart }
493d95b3509SRandall Stewart
494d95b3509SRandall Stewart static int
allocstall2(struct counters * cpu,int pos)495d95b3509SRandall Stewart allocstall2(struct counters *cpu, int pos)
496d95b3509SRandall Stewart {
497d95b3509SRandall Stewart /* 2 - PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */
498d95b3509SRandall Stewart int ret;
499d95b3509SRandall Stewart struct counters *partial;
500d95b3509SRandall Stewart struct counters *unhalt;
501d95b3509SRandall Stewart double un, par, res;
502d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
503d95b3509SRandall Stewart partial = find_counter(cpu, "PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP");
504d95b3509SRandall Stewart if (pos != -1) {
505d95b3509SRandall Stewart par = partial->vals[pos] * 1.0;
506d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
507d95b3509SRandall Stewart } else {
508d95b3509SRandall Stewart par = partial->sum * 1.0;
509d95b3509SRandall Stewart un = unhalt->sum * 1.0;
510d95b3509SRandall Stewart }
511d95b3509SRandall Stewart res = par/un;
512d95b3509SRandall Stewart ret = printf("%1.3f", res);
513d95b3509SRandall Stewart return(ret);
514d95b3509SRandall Stewart }
515d95b3509SRandall Stewart
516d95b3509SRandall Stewart static int
br_mispredict(struct counters * cpu,int pos)517d95b3509SRandall Stewart br_mispredict(struct counters *cpu, int pos)
518d95b3509SRandall Stewart {
519d95b3509SRandall Stewart struct counters *brctr;
520d95b3509SRandall Stewart struct counters *unhalt;
521d95b3509SRandall Stewart int ret;
522d95b3509SRandall Stewart /* 3 - (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */
523d95b3509SRandall Stewart double br, un, con, res;
524d95b3509SRandall Stewart con = 20.0;
525d95b3509SRandall Stewart
526d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
527d95b3509SRandall Stewart brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES");
528d95b3509SRandall Stewart if (pos != -1) {
529d95b3509SRandall Stewart br = brctr->vals[pos] * 1.0;
530d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
531d95b3509SRandall Stewart } else {
532d95b3509SRandall Stewart br = brctr->sum * 1.0;
533d95b3509SRandall Stewart un = unhalt->sum * 1.0;
534d95b3509SRandall Stewart }
535d95b3509SRandall Stewart res = (con * br)/un;
536d95b3509SRandall Stewart ret = printf("%1.3f", res);
537d95b3509SRandall Stewart return(ret);
538d95b3509SRandall Stewart }
539d95b3509SRandall Stewart
540d95b3509SRandall Stewart static int
br_mispredictib(struct counters * cpu,int pos)541d95b3509SRandall Stewart br_mispredictib(struct counters *cpu, int pos)
542d95b3509SRandall Stewart {
543d95b3509SRandall Stewart struct counters *brctr;
544d95b3509SRandall Stewart struct counters *unhalt;
545d95b3509SRandall Stewart struct counters *clear, *clear2, *clear3;
546d95b3509SRandall Stewart struct counters *uops;
547d95b3509SRandall Stewart struct counters *recv;
548d95b3509SRandall Stewart struct counters *iss;
549d95b3509SRandall Stewart /* "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",*/
550d95b3509SRandall Stewart int ret;
551d95b3509SRandall Stewart /*
552eef0660aSRandall Stewart * (BR_MISP_RETIRED.ALL_BRANCHES /
553eef0660aSRandall Stewart * (BR_MISP_RETIRED.ALL_BRANCHES +
554eef0660aSRandall Stewart * MACHINE_CLEAR.COUNT) *
555eef0660aSRandall Stewart * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) / (4 * CPU_CLK_UNHALTED.THREAD)))
556d95b3509SRandall Stewart *
557d95b3509SRandall Stewart */
558d95b3509SRandall Stewart double br, cl, cl2, cl3, uo, re, un, con, res, is;
559d95b3509SRandall Stewart con = 4.0;
560d95b3509SRandall Stewart
561d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
562d95b3509SRandall Stewart brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES");
563d95b3509SRandall Stewart clear = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING");
564d95b3509SRandall Stewart clear2 = find_counter(cpu, "MACHINE_CLEARS.SMC");
565d95b3509SRandall Stewart clear3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV");
566d95b3509SRandall Stewart uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
567d95b3509SRandall Stewart iss = find_counter(cpu, "UOPS_ISSUED.ANY");
568d95b3509SRandall Stewart recv = find_counter(cpu, "INT_MISC.RECOVERY_CYCLES");
569d95b3509SRandall Stewart if (pos != -1) {
570d95b3509SRandall Stewart br = brctr->vals[pos] * 1.0;
571d95b3509SRandall Stewart cl = clear->vals[pos] * 1.0;
572d95b3509SRandall Stewart cl2 = clear2->vals[pos] * 1.0;
573d95b3509SRandall Stewart cl3 = clear3->vals[pos] * 1.0;
574d95b3509SRandall Stewart uo = uops->vals[pos] * 1.0;
575d95b3509SRandall Stewart re = recv->vals[pos] * 1.0;
576d95b3509SRandall Stewart is = iss->vals[pos] * 1.0;
577d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
578d95b3509SRandall Stewart } else {
579d95b3509SRandall Stewart br = brctr->sum * 1.0;
580d95b3509SRandall Stewart cl = clear->sum * 1.0;
581d95b3509SRandall Stewart cl2 = clear2->sum * 1.0;
582d95b3509SRandall Stewart cl3 = clear3->sum * 1.0;
583d95b3509SRandall Stewart uo = uops->sum * 1.0;
584d95b3509SRandall Stewart re = recv->sum * 1.0;
585d95b3509SRandall Stewart is = iss->sum * 1.0;
586d95b3509SRandall Stewart un = unhalt->sum * 1.0;
587d95b3509SRandall Stewart }
588d95b3509SRandall Stewart res = (br/(br + cl + cl2 + cl3) * ((is - uo + con * re) / (con * un)));
589d95b3509SRandall Stewart ret = printf("%1.3f", res);
590d95b3509SRandall Stewart return(ret);
591d95b3509SRandall Stewart }
592d95b3509SRandall Stewart
593eef0660aSRandall Stewart
594d95b3509SRandall Stewart static int
br_mispredict_broad(struct counters * cpu,int pos)595ade40db3SRandall Stewart br_mispredict_broad(struct counters *cpu, int pos)
596ade40db3SRandall Stewart {
597ade40db3SRandall Stewart struct counters *brctr;
598ade40db3SRandall Stewart struct counters *unhalt;
599ade40db3SRandall Stewart struct counters *clear;
600ade40db3SRandall Stewart struct counters *uops;
601ade40db3SRandall Stewart struct counters *uops_ret;
602ade40db3SRandall Stewart struct counters *recv;
603ade40db3SRandall Stewart int ret;
604ade40db3SRandall Stewart double br, cl, uo, uo_r, re, con, un, res;
605ade40db3SRandall Stewart
606ade40db3SRandall Stewart con = 4.0;
607ade40db3SRandall Stewart
608ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
609ade40db3SRandall Stewart brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES");
610ade40db3SRandall Stewart clear = find_counter(cpu, "MACHINE_CLEARS.CYCLES");
611ade40db3SRandall Stewart uops = find_counter(cpu, "UOPS_ISSUED.ANY");
612ade40db3SRandall Stewart uops_ret = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
613ade40db3SRandall Stewart recv = find_counter(cpu, "INT_MISC.RECOVERY_CYCLES");
614ade40db3SRandall Stewart
615ade40db3SRandall Stewart if (pos != -1) {
616ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
617ade40db3SRandall Stewart br = brctr->vals[pos] * 1.0;
618ade40db3SRandall Stewart cl = clear->vals[pos] * 1.0;
619ade40db3SRandall Stewart uo = uops->vals[pos] * 1.0;
620ade40db3SRandall Stewart uo_r = uops_ret->vals[pos] * 1.0;
621ade40db3SRandall Stewart re = recv->vals[pos] * 1.0;
622ade40db3SRandall Stewart } else {
623ade40db3SRandall Stewart un = unhalt->sum * 1.0;
624ade40db3SRandall Stewart br = brctr->sum * 1.0;
625ade40db3SRandall Stewart cl = clear->sum * 1.0;
626ade40db3SRandall Stewart uo = uops->sum * 1.0;
627ade40db3SRandall Stewart uo_r = uops_ret->sum * 1.0;
628ade40db3SRandall Stewart re = recv->sum * 1.0;
629ade40db3SRandall Stewart }
630ade40db3SRandall Stewart res = br / (br + cl) * (uo - uo_r + con * re) / (un * con);
631ade40db3SRandall Stewart ret = printf("%1.3f", res);
632ade40db3SRandall Stewart return(ret);
633ade40db3SRandall Stewart }
634ade40db3SRandall Stewart
635ade40db3SRandall Stewart static int
splitloadib(struct counters * cpu,int pos)636d95b3509SRandall Stewart splitloadib(struct counters *cpu, int pos)
637d95b3509SRandall Stewart {
638d95b3509SRandall Stewart int ret;
639d95b3509SRandall Stewart struct counters *mem;
640d95b3509SRandall Stewart struct counters *l1d, *ldblock;
641d95b3509SRandall Stewart struct counters *unhalt;
642d95b3509SRandall Stewart double un, memd, res, l1, ldb;
643d95b3509SRandall Stewart /*
644eef0660aSRandall Stewart * ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) * LD_BLOCKS.NO_SR) / CPU_CLK_UNHALTED.THREAD_P
645eef0660aSRandall Stewart * "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1",
646d95b3509SRandall Stewart */
647d95b3509SRandall Stewart
648d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
649d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L1_MISS");
650d95b3509SRandall Stewart l1d = find_counter(cpu, "L1D_PEND_MISS.PENDING");
651d95b3509SRandall Stewart ldblock = find_counter(cpu, "LD_BLOCKS.NO_SR");
652d95b3509SRandall Stewart if (pos != -1) {
653d95b3509SRandall Stewart memd = mem->vals[pos] * 1.0;
654d95b3509SRandall Stewart l1 = l1d->vals[pos] * 1.0;
655d95b3509SRandall Stewart ldb = ldblock->vals[pos] * 1.0;
656d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
657d95b3509SRandall Stewart } else {
658d95b3509SRandall Stewart memd = mem->sum * 1.0;
659d95b3509SRandall Stewart l1 = l1d->sum * 1.0;
660d95b3509SRandall Stewart ldb = ldblock->sum * 1.0;
661d95b3509SRandall Stewart un = unhalt->sum * 1.0;
662d95b3509SRandall Stewart }
663d95b3509SRandall Stewart res = ((l1 / memd) * ldb)/un;
664d95b3509SRandall Stewart ret = printf("%1.3f", res);
665d95b3509SRandall Stewart return(ret);
666d95b3509SRandall Stewart }
667d95b3509SRandall Stewart
668eef0660aSRandall Stewart
669d95b3509SRandall Stewart static int
splitload(struct counters * cpu,int pos)670d95b3509SRandall Stewart splitload(struct counters *cpu, int pos)
671d95b3509SRandall Stewart {
672d95b3509SRandall Stewart int ret;
673d95b3509SRandall Stewart struct counters *mem;
674d95b3509SRandall Stewart struct counters *unhalt;
675d95b3509SRandall Stewart double con, un, memd, res;
676eef0660aSRandall Stewart /* 4 - (MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/
677058ccb75SRandall Stewart
678eef0660aSRandall Stewart con = 5.0;
679eef0660aSRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
680eef0660aSRandall Stewart mem = find_counter(cpu, "MEM_UOPS_RETIRED.SPLIT_LOADS");
681eef0660aSRandall Stewart if (pos != -1) {
682eef0660aSRandall Stewart memd = mem->vals[pos] * 1.0;
683eef0660aSRandall Stewart un = unhalt->vals[pos] * 1.0;
684eef0660aSRandall Stewart } else {
685eef0660aSRandall Stewart memd = mem->sum * 1.0;
686eef0660aSRandall Stewart un = unhalt->sum * 1.0;
687eef0660aSRandall Stewart }
688eef0660aSRandall Stewart res = (memd * con)/un;
689eef0660aSRandall Stewart ret = printf("%1.3f", res);
690eef0660aSRandall Stewart return(ret);
691eef0660aSRandall Stewart }
692eef0660aSRandall Stewart
693eef0660aSRandall Stewart
694eef0660aSRandall Stewart static int
splitload_sb(struct counters * cpu,int pos)695eef0660aSRandall Stewart splitload_sb(struct counters *cpu, int pos)
696eef0660aSRandall Stewart {
697eef0660aSRandall Stewart int ret;
698eef0660aSRandall Stewart struct counters *mem;
699eef0660aSRandall Stewart struct counters *unhalt;
700eef0660aSRandall Stewart double con, un, memd, res;
701d95b3509SRandall Stewart /* 4 - (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/
702d95b3509SRandall Stewart
703d95b3509SRandall Stewart con = 5.0;
704d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
705d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_LOADS");
706d95b3509SRandall Stewart if (pos != -1) {
707d95b3509SRandall Stewart memd = mem->vals[pos] * 1.0;
708d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
709d95b3509SRandall Stewart } else {
710d95b3509SRandall Stewart memd = mem->sum * 1.0;
711d95b3509SRandall Stewart un = unhalt->sum * 1.0;
712d95b3509SRandall Stewart }
713d95b3509SRandall Stewart res = (memd * con)/un;
714d95b3509SRandall Stewart ret = printf("%1.3f", res);
715d95b3509SRandall Stewart return(ret);
716d95b3509SRandall Stewart }
717d95b3509SRandall Stewart
718eef0660aSRandall Stewart
719d95b3509SRandall Stewart static int
splitstore_sb(struct counters * cpu,int pos)720eef0660aSRandall Stewart splitstore_sb(struct counters *cpu, int pos)
721d95b3509SRandall Stewart {
722eef0660aSRandall Stewart /* 5 - MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES (thresh > 0.01) */
723d95b3509SRandall Stewart int ret;
724d95b3509SRandall Stewart struct counters *mem_split;
725d95b3509SRandall Stewart struct counters *mem_stores;
726d95b3509SRandall Stewart double memsplit, memstore, res;
727d95b3509SRandall Stewart mem_split = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_STORES");
728d95b3509SRandall Stewart mem_stores = find_counter(cpu, "MEM_UOP_RETIRED.ALL_STORES");
729d95b3509SRandall Stewart if (pos != -1) {
730d95b3509SRandall Stewart memsplit = mem_split->vals[pos] * 1.0;
731d95b3509SRandall Stewart memstore = mem_stores->vals[pos] * 1.0;
732d95b3509SRandall Stewart } else {
733d95b3509SRandall Stewart memsplit = mem_split->sum * 1.0;
734d95b3509SRandall Stewart memstore = mem_stores->sum * 1.0;
735d95b3509SRandall Stewart }
736d95b3509SRandall Stewart res = memsplit/memstore;
737d95b3509SRandall Stewart ret = printf("%1.3f", res);
738d95b3509SRandall Stewart return(ret);
739d95b3509SRandall Stewart }
740d95b3509SRandall Stewart
741d95b3509SRandall Stewart
742eef0660aSRandall Stewart
743eef0660aSRandall Stewart static int
splitstore(struct counters * cpu,int pos)744eef0660aSRandall Stewart splitstore(struct counters *cpu, int pos)
745eef0660aSRandall Stewart {
746eef0660aSRandall Stewart /* 5 - MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES (thresh > 0.01) */
747eef0660aSRandall Stewart int ret;
748eef0660aSRandall Stewart struct counters *mem_split;
749eef0660aSRandall Stewart struct counters *mem_stores;
750eef0660aSRandall Stewart double memsplit, memstore, res;
751eef0660aSRandall Stewart mem_split = find_counter(cpu, "MEM_UOPS_RETIRED.SPLIT_STORES");
752eef0660aSRandall Stewart mem_stores = find_counter(cpu, "MEM_UOPS_RETIRED.ALL_STORES");
753eef0660aSRandall Stewart if (pos != -1) {
754eef0660aSRandall Stewart memsplit = mem_split->vals[pos] * 1.0;
755eef0660aSRandall Stewart memstore = mem_stores->vals[pos] * 1.0;
756eef0660aSRandall Stewart } else {
757eef0660aSRandall Stewart memsplit = mem_split->sum * 1.0;
758eef0660aSRandall Stewart memstore = mem_stores->sum * 1.0;
759eef0660aSRandall Stewart }
760eef0660aSRandall Stewart res = memsplit/memstore;
761eef0660aSRandall Stewart ret = printf("%1.3f", res);
762eef0660aSRandall Stewart return(ret);
763eef0660aSRandall Stewart }
764eef0660aSRandall Stewart
765eef0660aSRandall Stewart
766d95b3509SRandall Stewart static int
contested(struct counters * cpu,int pos)767d95b3509SRandall Stewart contested(struct counters *cpu, int pos)
768d95b3509SRandall Stewart {
769eef0660aSRandall Stewart /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */
770d95b3509SRandall Stewart int ret;
771d95b3509SRandall Stewart struct counters *mem;
772d95b3509SRandall Stewart struct counters *unhalt;
773d95b3509SRandall Stewart double con, un, memd, res;
774d95b3509SRandall Stewart
775d95b3509SRandall Stewart con = 60.0;
776d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
777d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
778d95b3509SRandall Stewart if (pos != -1) {
779d95b3509SRandall Stewart memd = mem->vals[pos] * 1.0;
780d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
781d95b3509SRandall Stewart } else {
782d95b3509SRandall Stewart memd = mem->sum * 1.0;
783d95b3509SRandall Stewart un = unhalt->sum * 1.0;
784d95b3509SRandall Stewart }
785d95b3509SRandall Stewart res = (memd * con)/un;
786d95b3509SRandall Stewart ret = printf("%1.3f", res);
787d95b3509SRandall Stewart return(ret);
788d95b3509SRandall Stewart }
789d95b3509SRandall Stewart
790d95b3509SRandall Stewart static int
contested_has(struct counters * cpu,int pos)791d95b3509SRandall Stewart contested_has(struct counters *cpu, int pos)
792d95b3509SRandall Stewart {
793eef0660aSRandall Stewart /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */
794d95b3509SRandall Stewart int ret;
795d95b3509SRandall Stewart struct counters *mem;
796d95b3509SRandall Stewart struct counters *unhalt;
797d95b3509SRandall Stewart double con, un, memd, res;
798d95b3509SRandall Stewart
799d95b3509SRandall Stewart con = 84.0;
800d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
801d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
802d95b3509SRandall Stewart if (pos != -1) {
803d95b3509SRandall Stewart memd = mem->vals[pos] * 1.0;
804d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
805d95b3509SRandall Stewart } else {
806d95b3509SRandall Stewart memd = mem->sum * 1.0;
807d95b3509SRandall Stewart un = unhalt->sum * 1.0;
808d95b3509SRandall Stewart }
809d95b3509SRandall Stewart res = (memd * con)/un;
810d95b3509SRandall Stewart ret = printf("%1.3f", res);
811d95b3509SRandall Stewart return(ret);
812d95b3509SRandall Stewart }
813d95b3509SRandall Stewart
814ade40db3SRandall Stewart static int
contestedbroad(struct counters * cpu,int pos)815ade40db3SRandall Stewart contestedbroad(struct counters *cpu, int pos)
816ade40db3SRandall Stewart {
817eef0660aSRandall Stewart /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */
818ade40db3SRandall Stewart int ret;
819ade40db3SRandall Stewart struct counters *mem;
820ade40db3SRandall Stewart struct counters *mem2;
821ade40db3SRandall Stewart struct counters *unhalt;
822ade40db3SRandall Stewart double con, un, memd, memtoo, res;
823ade40db3SRandall Stewart
824ade40db3SRandall Stewart con = 84.0;
825ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
826ade40db3SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
827ade40db3SRandall Stewart mem2 = find_counter(cpu,"MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS");
828ade40db3SRandall Stewart
829ade40db3SRandall Stewart if (pos != -1) {
830ade40db3SRandall Stewart memd = mem->vals[pos] * 1.0;
831ade40db3SRandall Stewart memtoo = mem2->vals[pos] * 1.0;
832ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
833ade40db3SRandall Stewart } else {
834ade40db3SRandall Stewart memd = mem->sum * 1.0;
835ade40db3SRandall Stewart memtoo = mem2->sum * 1.0;
836ade40db3SRandall Stewart un = unhalt->sum * 1.0;
837ade40db3SRandall Stewart }
838ade40db3SRandall Stewart res = ((memd * con) + memtoo)/un;
839ade40db3SRandall Stewart ret = printf("%1.3f", res);
840ade40db3SRandall Stewart return(ret);
841ade40db3SRandall Stewart }
842ade40db3SRandall Stewart
843d95b3509SRandall Stewart
844d95b3509SRandall Stewart static int
blockstoreforward(struct counters * cpu,int pos)845d95b3509SRandall Stewart blockstoreforward(struct counters *cpu, int pos)
846d95b3509SRandall Stewart {
847eef0660aSRandall Stewart /* 7 - (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .05)*/
848d95b3509SRandall Stewart int ret;
849d95b3509SRandall Stewart struct counters *ldb;
850d95b3509SRandall Stewart struct counters *unhalt;
851d95b3509SRandall Stewart double con, un, ld, res;
852d95b3509SRandall Stewart
853d95b3509SRandall Stewart con = 13.0;
854d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
855d95b3509SRandall Stewart ldb = find_counter(cpu, "LD_BLOCKS_STORE_FORWARD");
856d95b3509SRandall Stewart if (pos != -1) {
857d95b3509SRandall Stewart ld = ldb->vals[pos] * 1.0;
858d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
859d95b3509SRandall Stewart } else {
860d95b3509SRandall Stewart ld = ldb->sum * 1.0;
861d95b3509SRandall Stewart un = unhalt->sum * 1.0;
862d95b3509SRandall Stewart }
863d95b3509SRandall Stewart res = (ld * con)/un;
864d95b3509SRandall Stewart ret = printf("%1.3f", res);
865d95b3509SRandall Stewart return(ret);
866d95b3509SRandall Stewart }
867d95b3509SRandall Stewart
868d95b3509SRandall Stewart static int
cache2(struct counters * cpu,int pos)869d95b3509SRandall Stewart cache2(struct counters *cpu, int pos)
870d95b3509SRandall Stewart {
871eef0660aSRandall Stewart /* ** Suspect ***
872eef0660aSRandall Stewart * 8 - ((MEM_LOAD_RETIRED.L3_HIT * 26) + (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) +
873eef0660aSRandall Stewart * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
874d95b3509SRandall Stewart */
875d95b3509SRandall Stewart int ret;
876d95b3509SRandall Stewart struct counters *mem1, *mem2, *mem3;
877d95b3509SRandall Stewart struct counters *unhalt;
878d95b3509SRandall Stewart double con1, con2, con3, un, me_1, me_2, me_3, res;
879d95b3509SRandall Stewart
880d95b3509SRandall Stewart con1 = 26.0;
881d95b3509SRandall Stewart con2 = 43.0;
882d95b3509SRandall Stewart con3 = 60.0;
883d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
884d95b3509SRandall Stewart /* Call for MEM_LOAD_RETIRED.L3_HIT possibly MEM_LOAD_UOPS_RETIRED.LLC_HIT ?*/
885d95b3509SRandall Stewart mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT");
886d95b3509SRandall Stewart mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT");
887d95b3509SRandall Stewart mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
888d95b3509SRandall Stewart if (pos != -1) {
889d95b3509SRandall Stewart me_1 = mem1->vals[pos] * 1.0;
890d95b3509SRandall Stewart me_2 = mem2->vals[pos] * 1.0;
891d95b3509SRandall Stewart me_3 = mem3->vals[pos] * 1.0;
892d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
893d95b3509SRandall Stewart } else {
894d95b3509SRandall Stewart me_1 = mem1->sum * 1.0;
895d95b3509SRandall Stewart me_2 = mem2->sum * 1.0;
896d95b3509SRandall Stewart me_3 = mem3->sum * 1.0;
897d95b3509SRandall Stewart un = unhalt->sum * 1.0;
898d95b3509SRandall Stewart }
899d95b3509SRandall Stewart res = ((me_1 * con1) + (me_2 * con2) + (me_3 * con3))/un;
900d95b3509SRandall Stewart ret = printf("%1.3f", res);
901d95b3509SRandall Stewart return(ret);
902d95b3509SRandall Stewart }
903d95b3509SRandall Stewart
904d95b3509SRandall Stewart static int
datasharing(struct counters * cpu,int pos)905d95b3509SRandall Stewart datasharing(struct counters *cpu, int pos)
906d95b3509SRandall Stewart {
907d95b3509SRandall Stewart /*
908eef0660aSRandall Stewart * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
909d95b3509SRandall Stewart */
910d95b3509SRandall Stewart int ret;
911d95b3509SRandall Stewart struct counters *mem;
912d95b3509SRandall Stewart struct counters *unhalt;
913d95b3509SRandall Stewart double con, res, me, un;
914d95b3509SRandall Stewart
915d95b3509SRandall Stewart con = 43.0;
916d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
917d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT");
918d95b3509SRandall Stewart if (pos != -1) {
919d95b3509SRandall Stewart me = mem->vals[pos] * 1.0;
920d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
921d95b3509SRandall Stewart } else {
922d95b3509SRandall Stewart me = mem->sum * 1.0;
923d95b3509SRandall Stewart un = unhalt->sum * 1.0;
924d95b3509SRandall Stewart }
925d95b3509SRandall Stewart res = (me * con)/un;
926d95b3509SRandall Stewart ret = printf("%1.3f", res);
927d95b3509SRandall Stewart return(ret);
928d95b3509SRandall Stewart
929d95b3509SRandall Stewart }
930d95b3509SRandall Stewart
931d95b3509SRandall Stewart
932d95b3509SRandall Stewart static int
datasharing_has(struct counters * cpu,int pos)933d95b3509SRandall Stewart datasharing_has(struct counters *cpu, int pos)
934d95b3509SRandall Stewart {
935d95b3509SRandall Stewart /*
936eef0660aSRandall Stewart * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
937d95b3509SRandall Stewart */
938d95b3509SRandall Stewart int ret;
939d95b3509SRandall Stewart struct counters *mem;
940d95b3509SRandall Stewart struct counters *unhalt;
941d95b3509SRandall Stewart double con, res, me, un;
942d95b3509SRandall Stewart
943d95b3509SRandall Stewart con = 72.0;
944d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
945d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT");
946d95b3509SRandall Stewart if (pos != -1) {
947d95b3509SRandall Stewart me = mem->vals[pos] * 1.0;
948d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
949d95b3509SRandall Stewart } else {
950d95b3509SRandall Stewart me = mem->sum * 1.0;
951d95b3509SRandall Stewart un = unhalt->sum * 1.0;
952d95b3509SRandall Stewart }
953d95b3509SRandall Stewart res = (me * con)/un;
954d95b3509SRandall Stewart ret = printf("%1.3f", res);
955d95b3509SRandall Stewart return(ret);
956d95b3509SRandall Stewart
957d95b3509SRandall Stewart }
958d95b3509SRandall Stewart
959d95b3509SRandall Stewart
960d95b3509SRandall Stewart static int
cache2ib(struct counters * cpu,int pos)961d95b3509SRandall Stewart cache2ib(struct counters *cpu, int pos)
962d95b3509SRandall Stewart {
963d95b3509SRandall Stewart /*
964eef0660aSRandall Stewart * (29 * MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
965d95b3509SRandall Stewart */
966d95b3509SRandall Stewart int ret;
967d95b3509SRandall Stewart struct counters *mem;
968d95b3509SRandall Stewart struct counters *unhalt;
969d95b3509SRandall Stewart double con, un, me, res;
970d95b3509SRandall Stewart
971d95b3509SRandall Stewart con = 29.0;
972d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
973d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT");
974d95b3509SRandall Stewart if (pos != -1) {
975d95b3509SRandall Stewart me = mem->vals[pos] * 1.0;
976d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
977d95b3509SRandall Stewart } else {
978d95b3509SRandall Stewart me = mem->sum * 1.0;
979d95b3509SRandall Stewart un = unhalt->sum * 1.0;
980d95b3509SRandall Stewart }
981d95b3509SRandall Stewart res = (con * me)/un;
982d95b3509SRandall Stewart ret = printf("%1.3f", res);
983d95b3509SRandall Stewart return(ret);
984d95b3509SRandall Stewart }
985d95b3509SRandall Stewart
986d95b3509SRandall Stewart static int
cache2has(struct counters * cpu,int pos)987d95b3509SRandall Stewart cache2has(struct counters *cpu, int pos)
988d95b3509SRandall Stewart {
989d95b3509SRandall Stewart /*
990d95b3509SRandall Stewart * Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \
991d95b3509SRandall Stewart * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) +
992eef0660aSRandall Stewart * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84))
993eef0660aSRandall Stewart * / CPU_CLK_UNHALTED.THREAD_P
994d95b3509SRandall Stewart */
995d95b3509SRandall Stewart int ret;
996d95b3509SRandall Stewart struct counters *mem1, *mem2, *mem3;
997d95b3509SRandall Stewart struct counters *unhalt;
998d95b3509SRandall Stewart double con1, con2, con3, un, me1, me2, me3, res;
999d95b3509SRandall Stewart
1000d95b3509SRandall Stewart con1 = 36.0;
1001d95b3509SRandall Stewart con2 = 72.0;
1002d95b3509SRandall Stewart con3 = 84.0;
1003d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1004d95b3509SRandall Stewart mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT");
1005d95b3509SRandall Stewart mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT");
1006d95b3509SRandall Stewart mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
1007d95b3509SRandall Stewart if (pos != -1) {
1008d95b3509SRandall Stewart me1 = mem1->vals[pos] * 1.0;
1009d95b3509SRandall Stewart me2 = mem2->vals[pos] * 1.0;
1010d95b3509SRandall Stewart me3 = mem3->vals[pos] * 1.0;
1011d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1012d95b3509SRandall Stewart } else {
1013d95b3509SRandall Stewart me1 = mem1->sum * 1.0;
1014d95b3509SRandall Stewart me2 = mem2->sum * 1.0;
1015d95b3509SRandall Stewart me3 = mem3->sum * 1.0;
1016d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1017d95b3509SRandall Stewart }
1018d95b3509SRandall Stewart res = ((me1 * con1) + (me2 * con2) + (me3 * con3))/un;
1019d95b3509SRandall Stewart ret = printf("%1.3f", res);
1020d95b3509SRandall Stewart return(ret);
1021d95b3509SRandall Stewart }
1022d95b3509SRandall Stewart
1023eef0660aSRandall Stewart
1024d95b3509SRandall Stewart static int
cache2broad(struct counters * cpu,int pos)1025ade40db3SRandall Stewart cache2broad(struct counters *cpu, int pos)
1026ade40db3SRandall Stewart {
1027ade40db3SRandall Stewart /*
1028eef0660aSRandall Stewart * (29 * MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
1029ade40db3SRandall Stewart */
1030ade40db3SRandall Stewart int ret;
1031ade40db3SRandall Stewart struct counters *mem;
1032ade40db3SRandall Stewart struct counters *unhalt;
1033ade40db3SRandall Stewart double con, un, me, res;
1034ade40db3SRandall Stewart
1035ade40db3SRandall Stewart con = 36.0;
1036ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1037ade40db3SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L3_HIT");
1038ade40db3SRandall Stewart if (pos != -1) {
1039ade40db3SRandall Stewart me = mem->vals[pos] * 1.0;
1040ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1041ade40db3SRandall Stewart } else {
1042ade40db3SRandall Stewart me = mem->sum * 1.0;
1043ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1044ade40db3SRandall Stewart }
1045ade40db3SRandall Stewart res = (con * me)/un;
1046ade40db3SRandall Stewart ret = printf("%1.3f", res);
1047ade40db3SRandall Stewart return(ret);
1048ade40db3SRandall Stewart }
1049ade40db3SRandall Stewart
1050ade40db3SRandall Stewart
1051ade40db3SRandall Stewart static int
cache1(struct counters * cpu,int pos)1052d95b3509SRandall Stewart cache1(struct counters *cpu, int pos)
1053d95b3509SRandall Stewart {
1054eef0660aSRandall Stewart /* 9 - (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */
1055d95b3509SRandall Stewart int ret;
1056d95b3509SRandall Stewart struct counters *mem;
1057d95b3509SRandall Stewart struct counters *unhalt;
1058d95b3509SRandall Stewart double con, un, me, res;
1059d95b3509SRandall Stewart
1060d95b3509SRandall Stewart con = 180.0;
1061d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1062d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS");
1063d95b3509SRandall Stewart if (pos != -1) {
1064d95b3509SRandall Stewart me = mem->vals[pos] * 1.0;
1065d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1066d95b3509SRandall Stewart } else {
1067d95b3509SRandall Stewart me = mem->sum * 1.0;
1068d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1069d95b3509SRandall Stewart }
1070d95b3509SRandall Stewart res = (me * con)/un;
1071d95b3509SRandall Stewart ret = printf("%1.3f", res);
1072d95b3509SRandall Stewart return(ret);
1073d95b3509SRandall Stewart }
1074d95b3509SRandall Stewart
1075d95b3509SRandall Stewart static int
cache1ib(struct counters * cpu,int pos)1076d95b3509SRandall Stewart cache1ib(struct counters *cpu, int pos)
1077d95b3509SRandall Stewart {
1078eef0660aSRandall Stewart /* 9 - (MEM_LOAD_UOPS_L3_MISS_RETIRED.LCOAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */
1079d95b3509SRandall Stewart int ret;
1080d95b3509SRandall Stewart struct counters *mem;
1081d95b3509SRandall Stewart struct counters *unhalt;
1082d95b3509SRandall Stewart double con, un, me, res;
1083d95b3509SRandall Stewart
1084d95b3509SRandall Stewart con = 180.0;
1085d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1086d95b3509SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM");
1087d95b3509SRandall Stewart if (pos != -1) {
1088d95b3509SRandall Stewart me = mem->vals[pos] * 1.0;
1089d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1090d95b3509SRandall Stewart } else {
1091d95b3509SRandall Stewart me = mem->sum * 1.0;
1092d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1093d95b3509SRandall Stewart }
1094d95b3509SRandall Stewart res = (me * con)/un;
1095d95b3509SRandall Stewart ret = printf("%1.3f", res);
1096d95b3509SRandall Stewart return(ret);
1097d95b3509SRandall Stewart }
1098d95b3509SRandall Stewart
1099d95b3509SRandall Stewart
1100d95b3509SRandall Stewart static int
cache1broad(struct counters * cpu,int pos)1101ade40db3SRandall Stewart cache1broad(struct counters *cpu, int pos)
1102ade40db3SRandall Stewart {
1103eef0660aSRandall Stewart /* 9 - (MEM_LOAD_UOPS_L3_MISS_RETIRED.LCOAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */
1104ade40db3SRandall Stewart int ret;
1105ade40db3SRandall Stewart struct counters *mem;
1106ade40db3SRandall Stewart struct counters *unhalt;
1107ade40db3SRandall Stewart double con, un, me, res;
1108ade40db3SRandall Stewart
1109ade40db3SRandall Stewart con = 180.0;
1110ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1111ade40db3SRandall Stewart mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L3_MISS");
1112ade40db3SRandall Stewart if (pos != -1) {
1113ade40db3SRandall Stewart me = mem->vals[pos] * 1.0;
1114ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1115ade40db3SRandall Stewart } else {
1116ade40db3SRandall Stewart me = mem->sum * 1.0;
1117ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1118ade40db3SRandall Stewart }
1119ade40db3SRandall Stewart res = (me * con)/un;
1120ade40db3SRandall Stewart ret = printf("%1.3f", res);
1121ade40db3SRandall Stewart return(ret);
1122ade40db3SRandall Stewart }
1123ade40db3SRandall Stewart
1124ade40db3SRandall Stewart
1125ade40db3SRandall Stewart static int
dtlb_missload(struct counters * cpu,int pos)1126d95b3509SRandall Stewart dtlb_missload(struct counters *cpu, int pos)
1127d95b3509SRandall Stewart {
1128eef0660aSRandall Stewart /* 10 - ((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P (t >=.1) */
1129d95b3509SRandall Stewart int ret;
1130d95b3509SRandall Stewart struct counters *dtlb_m, *dtlb_d;
1131d95b3509SRandall Stewart struct counters *unhalt;
1132d95b3509SRandall Stewart double con, un, d1, d2, res;
1133d95b3509SRandall Stewart
1134d95b3509SRandall Stewart con = 7.0;
1135d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1136d95b3509SRandall Stewart dtlb_m = find_counter(cpu, "DTLB_LOAD_MISSES.STLB_HIT");
1137d95b3509SRandall Stewart dtlb_d = find_counter(cpu, "DTLB_LOAD_MISSES.WALK_DURATION");
1138d95b3509SRandall Stewart if (pos != -1) {
1139d95b3509SRandall Stewart d1 = dtlb_m->vals[pos] * 1.0;
1140d95b3509SRandall Stewart d2 = dtlb_d->vals[pos] * 1.0;
1141d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1142d95b3509SRandall Stewart } else {
1143d95b3509SRandall Stewart d1 = dtlb_m->sum * 1.0;
1144d95b3509SRandall Stewart d2 = dtlb_d->sum * 1.0;
1145d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1146d95b3509SRandall Stewart }
1147d95b3509SRandall Stewart res = ((d1 * con) + d2)/un;
1148d95b3509SRandall Stewart ret = printf("%1.3f", res);
1149d95b3509SRandall Stewart return(ret);
1150d95b3509SRandall Stewart }
1151d95b3509SRandall Stewart
1152d95b3509SRandall Stewart static int
dtlb_missstore(struct counters * cpu,int pos)1153d95b3509SRandall Stewart dtlb_missstore(struct counters *cpu, int pos)
1154d95b3509SRandall Stewart {
1155d95b3509SRandall Stewart /*
1156eef0660aSRandall Stewart * ((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION) /
1157eef0660aSRandall Stewart * CPU_CLK_UNHALTED.THREAD_P (t >= .1)
1158d95b3509SRandall Stewart */
1159d95b3509SRandall Stewart int ret;
1160d95b3509SRandall Stewart struct counters *dtsb_m, *dtsb_d;
1161d95b3509SRandall Stewart struct counters *unhalt;
1162d95b3509SRandall Stewart double con, un, d1, d2, res;
1163d95b3509SRandall Stewart
1164d95b3509SRandall Stewart con = 7.0;
1165d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1166d95b3509SRandall Stewart dtsb_m = find_counter(cpu, "DTLB_STORE_MISSES.STLB_HIT");
1167d95b3509SRandall Stewart dtsb_d = find_counter(cpu, "DTLB_STORE_MISSES.WALK_DURATION");
1168d95b3509SRandall Stewart if (pos != -1) {
1169d95b3509SRandall Stewart d1 = dtsb_m->vals[pos] * 1.0;
1170d95b3509SRandall Stewart d2 = dtsb_d->vals[pos] * 1.0;
1171d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1172d95b3509SRandall Stewart } else {
1173d95b3509SRandall Stewart d1 = dtsb_m->sum * 1.0;
1174d95b3509SRandall Stewart d2 = dtsb_d->sum * 1.0;
1175d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1176d95b3509SRandall Stewart }
1177d95b3509SRandall Stewart res = ((d1 * con) + d2)/un;
1178d95b3509SRandall Stewart ret = printf("%1.3f", res);
1179d95b3509SRandall Stewart return(ret);
1180d95b3509SRandall Stewart }
1181d95b3509SRandall Stewart
1182d95b3509SRandall Stewart static int
itlb_miss(struct counters * cpu,int pos)1183d95b3509SRandall Stewart itlb_miss(struct counters *cpu, int pos)
1184d95b3509SRandall Stewart {
1185d95b3509SRandall Stewart /* ITLB_MISSES.WALK_DURATION / CPU_CLK_UNTHREAD_P IB */
1186d95b3509SRandall Stewart int ret;
1187d95b3509SRandall Stewart struct counters *itlb;
1188d95b3509SRandall Stewart struct counters *unhalt;
1189d95b3509SRandall Stewart double un, d1, res;
1190d95b3509SRandall Stewart
1191d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1192d95b3509SRandall Stewart itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION");
1193d95b3509SRandall Stewart if (pos != -1) {
1194d95b3509SRandall Stewart d1 = itlb->vals[pos] * 1.0;
1195d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1196d95b3509SRandall Stewart } else {
1197d95b3509SRandall Stewart d1 = itlb->sum * 1.0;
1198d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1199d95b3509SRandall Stewart }
1200d95b3509SRandall Stewart res = d1/un;
1201d95b3509SRandall Stewart ret = printf("%1.3f", res);
1202d95b3509SRandall Stewart return(ret);
1203d95b3509SRandall Stewart }
1204d95b3509SRandall Stewart
1205ade40db3SRandall Stewart
1206ade40db3SRandall Stewart static int
itlb_miss_broad(struct counters * cpu,int pos)1207ade40db3SRandall Stewart itlb_miss_broad(struct counters *cpu, int pos)
1208ade40db3SRandall Stewart {
1209eef0660aSRandall Stewart /* (7 * ITLB_MISSES.STLB_HIT_4K + ITLB_MISSES.WALK_DURATION) / CPU_CLK_UNTHREAD_P */
1210ade40db3SRandall Stewart int ret;
1211ade40db3SRandall Stewart struct counters *itlb;
1212ade40db3SRandall Stewart struct counters *unhalt;
1213ade40db3SRandall Stewart struct counters *four_k;
1214ade40db3SRandall Stewart double un, d1, res, k;
1215ade40db3SRandall Stewart
1216ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1217ade40db3SRandall Stewart itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION");
1218ade40db3SRandall Stewart four_k = find_counter(cpu, "ITLB_MISSES.STLB_HIT_4K");
1219ade40db3SRandall Stewart if (pos != -1) {
1220ade40db3SRandall Stewart d1 = itlb->vals[pos] * 1.0;
1221ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1222ade40db3SRandall Stewart k = four_k->vals[pos] * 1.0;
1223ade40db3SRandall Stewart } else {
1224ade40db3SRandall Stewart d1 = itlb->sum * 1.0;
1225ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1226ade40db3SRandall Stewart k = four_k->sum * 1.0;
1227ade40db3SRandall Stewart }
1228ade40db3SRandall Stewart res = (7.0 * k + d1)/un;
1229ade40db3SRandall Stewart ret = printf("%1.3f", res);
1230ade40db3SRandall Stewart return(ret);
1231ade40db3SRandall Stewart }
1232ade40db3SRandall Stewart
1233ade40db3SRandall Stewart
1234d95b3509SRandall Stewart static int
icache_miss(struct counters * cpu,int pos)1235d95b3509SRandall Stewart icache_miss(struct counters *cpu, int pos)
1236d95b3509SRandall Stewart {
1237eef0660aSRandall Stewart /* (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P IB */
1238d95b3509SRandall Stewart
1239d95b3509SRandall Stewart int ret;
1240d95b3509SRandall Stewart struct counters *itlb, *icache;
1241d95b3509SRandall Stewart struct counters *unhalt;
1242d95b3509SRandall Stewart double un, d1, ic, res;
1243d95b3509SRandall Stewart
1244d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1245d95b3509SRandall Stewart itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION");
1246d95b3509SRandall Stewart icache = find_counter(cpu, "ICACHE.IFETCH_STALL");
1247d95b3509SRandall Stewart if (pos != -1) {
1248d95b3509SRandall Stewart d1 = itlb->vals[pos] * 1.0;
1249d95b3509SRandall Stewart ic = icache->vals[pos] * 1.0;
1250d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1251d95b3509SRandall Stewart } else {
1252d95b3509SRandall Stewart d1 = itlb->sum * 1.0;
1253d95b3509SRandall Stewart ic = icache->sum * 1.0;
1254d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1255d95b3509SRandall Stewart }
1256d95b3509SRandall Stewart res = (ic-d1)/un;
1257d95b3509SRandall Stewart ret = printf("%1.3f", res);
1258d95b3509SRandall Stewart return(ret);
1259d95b3509SRandall Stewart
1260d95b3509SRandall Stewart }
1261d95b3509SRandall Stewart
1262d95b3509SRandall Stewart static int
icache_miss_has(struct counters * cpu,int pos)1263d95b3509SRandall Stewart icache_miss_has(struct counters *cpu, int pos)
1264d95b3509SRandall Stewart {
1265d95b3509SRandall Stewart /* (36 * ICACHE.MISSES) / CPU_CLK_UNHALTED.THREAD_P */
1266d95b3509SRandall Stewart
1267d95b3509SRandall Stewart int ret;
1268d95b3509SRandall Stewart struct counters *icache;
1269d95b3509SRandall Stewart struct counters *unhalt;
1270d95b3509SRandall Stewart double un, con, ic, res;
1271d95b3509SRandall Stewart
1272d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1273d95b3509SRandall Stewart icache = find_counter(cpu, "ICACHE.MISSES");
1274d95b3509SRandall Stewart con = 36.0;
1275d95b3509SRandall Stewart if (pos != -1) {
1276d95b3509SRandall Stewart ic = icache->vals[pos] * 1.0;
1277d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1278d95b3509SRandall Stewart } else {
1279d95b3509SRandall Stewart ic = icache->sum * 1.0;
1280d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1281d95b3509SRandall Stewart }
1282d95b3509SRandall Stewart res = (con * ic)/un;
1283d95b3509SRandall Stewart ret = printf("%1.3f", res);
1284d95b3509SRandall Stewart return(ret);
1285d95b3509SRandall Stewart
1286d95b3509SRandall Stewart }
1287d95b3509SRandall Stewart
1288d95b3509SRandall Stewart static int
lcp_stall(struct counters * cpu,int pos)1289d95b3509SRandall Stewart lcp_stall(struct counters *cpu, int pos)
1290d95b3509SRandall Stewart {
1291d95b3509SRandall Stewart /* ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P IB */
1292d95b3509SRandall Stewart int ret;
1293d95b3509SRandall Stewart struct counters *ild;
1294d95b3509SRandall Stewart struct counters *unhalt;
1295d95b3509SRandall Stewart double un, d1, res;
1296d95b3509SRandall Stewart
1297d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1298d95b3509SRandall Stewart ild = find_counter(cpu, "ILD_STALL.LCP");
1299d95b3509SRandall Stewart if (pos != -1) {
1300d95b3509SRandall Stewart d1 = ild->vals[pos] * 1.0;
1301d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1302d95b3509SRandall Stewart } else {
1303d95b3509SRandall Stewart d1 = ild->sum * 1.0;
1304d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1305d95b3509SRandall Stewart }
1306d95b3509SRandall Stewart res = d1/un;
1307d95b3509SRandall Stewart ret = printf("%1.3f", res);
1308d95b3509SRandall Stewart return(ret);
1309d95b3509SRandall Stewart
1310d95b3509SRandall Stewart }
1311d95b3509SRandall Stewart
1312d95b3509SRandall Stewart
1313d95b3509SRandall Stewart static int
frontendstall(struct counters * cpu,int pos)1314d95b3509SRandall Stewart frontendstall(struct counters *cpu, int pos)
1315d95b3509SRandall Stewart {
1316eef0660aSRandall Stewart /* 12 - IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4) (thresh >= .15) */
1317d95b3509SRandall Stewart int ret;
1318d95b3509SRandall Stewart struct counters *idq;
1319d95b3509SRandall Stewart struct counters *unhalt;
1320d95b3509SRandall Stewart double con, un, id, res;
1321d95b3509SRandall Stewart
1322d95b3509SRandall Stewart con = 4.0;
1323d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1324d95b3509SRandall Stewart idq = find_counter(cpu, "IDQ_UOPS_NOT_DELIVERED.CORE");
1325d95b3509SRandall Stewart if (pos != -1) {
1326d95b3509SRandall Stewart id = idq->vals[pos] * 1.0;
1327d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1328d95b3509SRandall Stewart } else {
1329d95b3509SRandall Stewart id = idq->sum * 1.0;
1330d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1331d95b3509SRandall Stewart }
1332d95b3509SRandall Stewart res = id/(un * con);
1333d95b3509SRandall Stewart ret = printf("%1.3f", res);
1334d95b3509SRandall Stewart return(ret);
1335d95b3509SRandall Stewart }
1336d95b3509SRandall Stewart
1337d95b3509SRandall Stewart static int
clears(struct counters * cpu,int pos)1338d95b3509SRandall Stewart clears(struct counters *cpu, int pos)
1339d95b3509SRandall Stewart {
1340eef0660aSRandall Stewart /* 13 - ((MACHINE_CLEARS.MEMORY_ORDERING + MACHINE_CLEARS.SMC + MACHINE_CLEARS.MASKMOV ) * 100 )
1341eef0660aSRandall Stewart * / CPU_CLK_UNHALTED.THREAD_P (thresh >= .02)*/
1342d95b3509SRandall Stewart
1343d95b3509SRandall Stewart int ret;
1344d95b3509SRandall Stewart struct counters *clr1, *clr2, *clr3;
1345d95b3509SRandall Stewart struct counters *unhalt;
1346d95b3509SRandall Stewart double con, un, cl1, cl2, cl3, res;
1347d95b3509SRandall Stewart
1348d95b3509SRandall Stewart con = 100.0;
1349d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1350d95b3509SRandall Stewart clr1 = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING");
1351d95b3509SRandall Stewart clr2 = find_counter(cpu, "MACHINE_CLEARS.SMC");
1352d95b3509SRandall Stewart clr3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV");
1353d95b3509SRandall Stewart
1354d95b3509SRandall Stewart if (pos != -1) {
1355d95b3509SRandall Stewart cl1 = clr1->vals[pos] * 1.0;
1356d95b3509SRandall Stewart cl2 = clr2->vals[pos] * 1.0;
1357d95b3509SRandall Stewart cl3 = clr3->vals[pos] * 1.0;
1358d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1359d95b3509SRandall Stewart } else {
1360d95b3509SRandall Stewart cl1 = clr1->sum * 1.0;
1361d95b3509SRandall Stewart cl2 = clr2->sum * 1.0;
1362d95b3509SRandall Stewart cl3 = clr3->sum * 1.0;
1363d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1364d95b3509SRandall Stewart }
1365d95b3509SRandall Stewart res = ((cl1 + cl2 + cl3) * con)/un;
1366d95b3509SRandall Stewart ret = printf("%1.3f", res);
1367d95b3509SRandall Stewart return(ret);
1368d95b3509SRandall Stewart }
1369d95b3509SRandall Stewart
1370eef0660aSRandall Stewart
1371eef0660aSRandall Stewart
1372d95b3509SRandall Stewart static int
clears_broad(struct counters * cpu,int pos)1373ade40db3SRandall Stewart clears_broad(struct counters *cpu, int pos)
1374ade40db3SRandall Stewart {
1375ade40db3SRandall Stewart int ret;
1376ade40db3SRandall Stewart struct counters *clr1, *clr2, *clr3, *cyc;
1377ade40db3SRandall Stewart struct counters *unhalt;
1378ade40db3SRandall Stewart double con, un, cl1, cl2, cl3, cy, res;
1379ade40db3SRandall Stewart
1380ade40db3SRandall Stewart con = 100.0;
1381ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1382ade40db3SRandall Stewart clr1 = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING");
1383ade40db3SRandall Stewart clr2 = find_counter(cpu, "MACHINE_CLEARS.SMC");
1384ade40db3SRandall Stewart clr3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV");
1385ade40db3SRandall Stewart cyc = find_counter(cpu, "MACHINE_CLEARS.CYCLES");
1386ade40db3SRandall Stewart if (pos != -1) {
1387ade40db3SRandall Stewart cl1 = clr1->vals[pos] * 1.0;
1388ade40db3SRandall Stewart cl2 = clr2->vals[pos] * 1.0;
1389ade40db3SRandall Stewart cl3 = clr3->vals[pos] * 1.0;
1390ade40db3SRandall Stewart cy = cyc->vals[pos] * 1.0;
1391ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1392ade40db3SRandall Stewart } else {
1393ade40db3SRandall Stewart cl1 = clr1->sum * 1.0;
1394ade40db3SRandall Stewart cl2 = clr2->sum * 1.0;
1395ade40db3SRandall Stewart cl3 = clr3->sum * 1.0;
1396ade40db3SRandall Stewart cy = cyc->sum * 1.0;
1397ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1398ade40db3SRandall Stewart }
1399ade40db3SRandall Stewart /* Formula not listed but extrapulated to add the cy ?? */
1400ade40db3SRandall Stewart res = ((cl1 + cl2 + cl3 + cy) * con)/un;
1401ade40db3SRandall Stewart ret = printf("%1.3f", res);
1402ade40db3SRandall Stewart return(ret);
1403ade40db3SRandall Stewart }
1404ade40db3SRandall Stewart
1405eef0660aSRandall Stewart
1406eef0660aSRandall Stewart
1407eef0660aSRandall Stewart
1408eef0660aSRandall Stewart
1409ade40db3SRandall Stewart static int
microassist(struct counters * cpu,int pos)1410d95b3509SRandall Stewart microassist(struct counters *cpu, int pos)
1411d95b3509SRandall Stewart {
1412d95b3509SRandall Stewart /* 14 - IDQ.MS_CYCLES / CPU_CLK_UNHALTED.THREAD_P (thresh > .05) */
1413d95b3509SRandall Stewart int ret;
1414d95b3509SRandall Stewart struct counters *idq;
1415d95b3509SRandall Stewart struct counters *unhalt;
1416d95b3509SRandall Stewart double un, id, res, con;
1417d95b3509SRandall Stewart
1418d95b3509SRandall Stewart con = 4.0;
1419d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1420d95b3509SRandall Stewart idq = find_counter(cpu, "IDQ.MS_UOPS");
1421d95b3509SRandall Stewart if (pos != -1) {
1422d95b3509SRandall Stewart id = idq->vals[pos] * 1.0;
1423d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1424d95b3509SRandall Stewart } else {
1425d95b3509SRandall Stewart id = idq->sum * 1.0;
1426d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1427d95b3509SRandall Stewart }
1428d95b3509SRandall Stewart res = id/(un * con);
1429d95b3509SRandall Stewart ret = printf("%1.3f", res);
1430d95b3509SRandall Stewart return(ret);
1431d95b3509SRandall Stewart }
1432d95b3509SRandall Stewart
1433eef0660aSRandall Stewart
1434ade40db3SRandall Stewart static int
microassist_broad(struct counters * cpu,int pos)1435ade40db3SRandall Stewart microassist_broad(struct counters *cpu, int pos)
1436ade40db3SRandall Stewart {
1437ade40db3SRandall Stewart int ret;
1438ade40db3SRandall Stewart struct counters *idq;
1439ade40db3SRandall Stewart struct counters *unhalt;
1440ade40db3SRandall Stewart struct counters *uopiss;
1441ade40db3SRandall Stewart struct counters *uopret;
1442ade40db3SRandall Stewart double un, id, res, con, uoi, uor;
1443ade40db3SRandall Stewart
1444ade40db3SRandall Stewart con = 4.0;
1445ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1446ade40db3SRandall Stewart idq = find_counter(cpu, "IDQ.MS_UOPS");
1447ade40db3SRandall Stewart uopiss = find_counter(cpu, "UOPS_ISSUED.ANY");
1448ade40db3SRandall Stewart uopret = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
1449ade40db3SRandall Stewart if (pos != -1) {
1450ade40db3SRandall Stewart id = idq->vals[pos] * 1.0;
1451ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1452ade40db3SRandall Stewart uoi = uopiss->vals[pos] * 1.0;
1453ade40db3SRandall Stewart uor = uopret->vals[pos] * 1.0;
1454ade40db3SRandall Stewart } else {
1455ade40db3SRandall Stewart id = idq->sum * 1.0;
1456ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1457ade40db3SRandall Stewart uoi = uopiss->sum * 1.0;
1458ade40db3SRandall Stewart uor = uopret->sum * 1.0;
1459ade40db3SRandall Stewart }
1460ade40db3SRandall Stewart res = (uor/uoi) * (id/(un * con));
1461ade40db3SRandall Stewart ret = printf("%1.3f", res);
1462ade40db3SRandall Stewart return(ret);
1463ade40db3SRandall Stewart }
1464d95b3509SRandall Stewart
1465eef0660aSRandall Stewart
1466d95b3509SRandall Stewart static int
aliasing(struct counters * cpu,int pos)1467d95b3509SRandall Stewart aliasing(struct counters *cpu, int pos)
1468d95b3509SRandall Stewart {
1469eef0660aSRandall Stewart /* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */
1470d95b3509SRandall Stewart int ret;
1471d95b3509SRandall Stewart struct counters *ld;
1472d95b3509SRandall Stewart struct counters *unhalt;
1473d95b3509SRandall Stewart double un, lds, con, res;
1474d95b3509SRandall Stewart
1475d95b3509SRandall Stewart con = 5.0;
1476d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1477d95b3509SRandall Stewart ld = find_counter(cpu, "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS");
1478d95b3509SRandall Stewart if (pos != -1) {
1479d95b3509SRandall Stewart lds = ld->vals[pos] * 1.0;
1480d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1481d95b3509SRandall Stewart } else {
1482d95b3509SRandall Stewart lds = ld->sum * 1.0;
1483d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1484d95b3509SRandall Stewart }
1485d95b3509SRandall Stewart res = (lds * con)/un;
1486d95b3509SRandall Stewart ret = printf("%1.3f", res);
1487d95b3509SRandall Stewart return(ret);
1488d95b3509SRandall Stewart }
1489d95b3509SRandall Stewart
1490d95b3509SRandall Stewart static int
aliasing_broad(struct counters * cpu,int pos)1491ade40db3SRandall Stewart aliasing_broad(struct counters *cpu, int pos)
1492ade40db3SRandall Stewart {
1493eef0660aSRandall Stewart /* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */
1494ade40db3SRandall Stewart int ret;
1495ade40db3SRandall Stewart struct counters *ld;
1496ade40db3SRandall Stewart struct counters *unhalt;
1497ade40db3SRandall Stewart double un, lds, con, res;
1498ade40db3SRandall Stewart
1499ade40db3SRandall Stewart con = 7.0;
1500ade40db3SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1501ade40db3SRandall Stewart ld = find_counter(cpu, "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS");
1502ade40db3SRandall Stewart if (pos != -1) {
1503ade40db3SRandall Stewart lds = ld->vals[pos] * 1.0;
1504ade40db3SRandall Stewart un = unhalt->vals[pos] * 1.0;
1505ade40db3SRandall Stewart } else {
1506ade40db3SRandall Stewart lds = ld->sum * 1.0;
1507ade40db3SRandall Stewart un = unhalt->sum * 1.0;
1508ade40db3SRandall Stewart }
1509ade40db3SRandall Stewart res = (lds * con)/un;
1510ade40db3SRandall Stewart ret = printf("%1.3f", res);
1511ade40db3SRandall Stewart return(ret);
1512ade40db3SRandall Stewart }
1513ade40db3SRandall Stewart
1514ade40db3SRandall Stewart
1515ade40db3SRandall Stewart static int
fpassists(struct counters * cpu,int pos)1516d95b3509SRandall Stewart fpassists(struct counters *cpu, int pos)
1517d95b3509SRandall Stewart {
1518d95b3509SRandall Stewart /* 16 - FP_ASSIST.ANY/INST_RETIRED.ANY_P */
1519d95b3509SRandall Stewart int ret;
1520d95b3509SRandall Stewart struct counters *fp;
1521d95b3509SRandall Stewart struct counters *inst;
1522d95b3509SRandall Stewart double un, fpd, res;
1523d95b3509SRandall Stewart
1524d95b3509SRandall Stewart inst = find_counter(cpu, "INST_RETIRED.ANY_P");
1525d95b3509SRandall Stewart fp = find_counter(cpu, "FP_ASSIST.ANY");
1526d95b3509SRandall Stewart if (pos != -1) {
1527d95b3509SRandall Stewart fpd = fp->vals[pos] * 1.0;
1528d95b3509SRandall Stewart un = inst->vals[pos] * 1.0;
1529d95b3509SRandall Stewart } else {
1530d95b3509SRandall Stewart fpd = fp->sum * 1.0;
1531d95b3509SRandall Stewart un = inst->sum * 1.0;
1532d95b3509SRandall Stewart }
1533d95b3509SRandall Stewart res = fpd/un;
1534d95b3509SRandall Stewart ret = printf("%1.3f", res);
1535d95b3509SRandall Stewart return(ret);
1536d95b3509SRandall Stewart }
1537d95b3509SRandall Stewart
1538d95b3509SRandall Stewart static int
otherassistavx(struct counters * cpu,int pos)1539d95b3509SRandall Stewart otherassistavx(struct counters *cpu, int pos)
1540d95b3509SRandall Stewart {
1541eef0660aSRandall Stewart /* 17 - (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/
1542d95b3509SRandall Stewart int ret;
1543d95b3509SRandall Stewart struct counters *oth;
1544d95b3509SRandall Stewart struct counters *unhalt;
1545d95b3509SRandall Stewart double un, ot, con, res;
1546d95b3509SRandall Stewart
1547d95b3509SRandall Stewart con = 75.0;
1548d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1549d95b3509SRandall Stewart oth = find_counter(cpu, "OTHER_ASSISTS.AVX_TO_SSE");
1550d95b3509SRandall Stewart if (pos != -1) {
1551d95b3509SRandall Stewart ot = oth->vals[pos] * 1.0;
1552d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1553d95b3509SRandall Stewart } else {
1554d95b3509SRandall Stewart ot = oth->sum * 1.0;
1555d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1556d95b3509SRandall Stewart }
1557d95b3509SRandall Stewart res = (ot * con)/un;
1558d95b3509SRandall Stewart ret = printf("%1.3f", res);
1559d95b3509SRandall Stewart return(ret);
1560d95b3509SRandall Stewart }
1561d95b3509SRandall Stewart
1562d95b3509SRandall Stewart static int
otherassistsse(struct counters * cpu,int pos)1563d95b3509SRandall Stewart otherassistsse(struct counters *cpu, int pos)
1564d95b3509SRandall Stewart {
1565d95b3509SRandall Stewart
1566d95b3509SRandall Stewart int ret;
1567d95b3509SRandall Stewart struct counters *oth;
1568d95b3509SRandall Stewart struct counters *unhalt;
1569d95b3509SRandall Stewart double un, ot, con, res;
1570d95b3509SRandall Stewart
1571eef0660aSRandall Stewart /* 18 (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/
1572d95b3509SRandall Stewart con = 75.0;
1573d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1574d95b3509SRandall Stewart oth = find_counter(cpu, "OTHER_ASSISTS.SSE_TO_AVX");
1575d95b3509SRandall Stewart if (pos != -1) {
1576d95b3509SRandall Stewart ot = oth->vals[pos] * 1.0;
1577d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1578d95b3509SRandall Stewart } else {
1579d95b3509SRandall Stewart ot = oth->sum * 1.0;
1580d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1581d95b3509SRandall Stewart }
1582d95b3509SRandall Stewart res = (ot * con)/un;
1583d95b3509SRandall Stewart ret = printf("%1.3f", res);
1584d95b3509SRandall Stewart return(ret);
1585d95b3509SRandall Stewart }
1586d95b3509SRandall Stewart
1587d95b3509SRandall Stewart static int
efficiency1(struct counters * cpu,int pos)1588d95b3509SRandall Stewart efficiency1(struct counters *cpu, int pos)
1589d95b3509SRandall Stewart {
1590d95b3509SRandall Stewart
1591d95b3509SRandall Stewart int ret;
1592d95b3509SRandall Stewart struct counters *uops;
1593d95b3509SRandall Stewart struct counters *unhalt;
1594d95b3509SRandall Stewart double un, ot, con, res;
1595d95b3509SRandall Stewart
1596eef0660aSRandall Stewart /* 19 (UOPS_RETIRED.RETIRE_SLOTS/(4*CPU_CLK_UNHALTED.THREAD_P) look if thresh < .9*/
1597d95b3509SRandall Stewart con = 4.0;
1598d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1599d95b3509SRandall Stewart uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
1600d95b3509SRandall Stewart if (pos != -1) {
1601d95b3509SRandall Stewart ot = uops->vals[pos] * 1.0;
1602d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1603d95b3509SRandall Stewart } else {
1604d95b3509SRandall Stewart ot = uops->sum * 1.0;
1605d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1606d95b3509SRandall Stewart }
1607d95b3509SRandall Stewart res = ot/(con * un);
1608d95b3509SRandall Stewart ret = printf("%1.3f", res);
1609d95b3509SRandall Stewart return(ret);
1610d95b3509SRandall Stewart }
1611d95b3509SRandall Stewart
1612d95b3509SRandall Stewart static int
efficiency2(struct counters * cpu,int pos)1613d95b3509SRandall Stewart efficiency2(struct counters *cpu, int pos)
1614d95b3509SRandall Stewart {
1615d95b3509SRandall Stewart
1616d95b3509SRandall Stewart int ret;
1617d95b3509SRandall Stewart struct counters *uops;
1618d95b3509SRandall Stewart struct counters *unhalt;
1619d95b3509SRandall Stewart double un, ot, res;
1620d95b3509SRandall Stewart
1621eef0660aSRandall Stewart /* 20 - CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P good if > 1. (comp factor)*/
1622d95b3509SRandall Stewart unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
1623d95b3509SRandall Stewart uops = find_counter(cpu, "INST_RETIRED.ANY_P");
1624d95b3509SRandall Stewart if (pos != -1) {
1625d95b3509SRandall Stewart ot = uops->vals[pos] * 1.0;
1626d95b3509SRandall Stewart un = unhalt->vals[pos] * 1.0;
1627d95b3509SRandall Stewart } else {
1628d95b3509SRandall Stewart ot = uops->sum * 1.0;
1629d95b3509SRandall Stewart un = unhalt->sum * 1.0;
1630d95b3509SRandall Stewart }
1631d95b3509SRandall Stewart res = un/ot;
1632d95b3509SRandall Stewart ret = printf("%1.3f", res);
1633d95b3509SRandall Stewart return(ret);
1634d95b3509SRandall Stewart }
1635d95b3509SRandall Stewart
1636d95b3509SRandall Stewart #define SANDY_BRIDGE_COUNT 20
1637d95b3509SRandall Stewart static struct cpu_entry sandy_bridge[SANDY_BRIDGE_COUNT] = {
1638d95b3509SRandall Stewart /*01*/ { "allocstall1", "thresh > .05",
1639d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW -w 1",
1640eef0660aSRandall Stewart allocstall1, 2 },
1641eef0660aSRandall Stewart /* -- not defined for SB right (partial-rat_stalls) 02*/
1642eef0660aSRandall Stewart { "allocstall2", "thresh > .05",
1643eef0660aSRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP -w 1",
1644eef0660aSRandall Stewart allocstall2, 2 },
1645d95b3509SRandall Stewart /*03*/ { "br_miss", "thresh >= .2",
1646d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1",
1647eef0660aSRandall Stewart br_mispredict, 2 },
1648d95b3509SRandall Stewart /*04*/ { "splitload", "thresh >= .1",
1649d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1",
1650eef0660aSRandall Stewart splitload_sb, 2 },
1651d95b3509SRandall Stewart /* 05*/ { "splitstore", "thresh >= .01",
1652d95b3509SRandall Stewart "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1",
1653eef0660aSRandall Stewart splitstore_sb, 2 },
1654d95b3509SRandall Stewart /*06*/ { "contested", "thresh >= .05",
1655d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1656eef0660aSRandall Stewart contested, 2 },
1657d95b3509SRandall Stewart /*07*/ { "blockstorefwd", "thresh >= .05",
1658d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1659eef0660aSRandall Stewart blockstoreforward, 2 },
1660d95b3509SRandall Stewart /*08*/ { "cache2", "thresh >= .2",
1661d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1662eef0660aSRandall Stewart cache2, 4 },
1663d95b3509SRandall Stewart /*09*/ { "cache1", "thresh >= .2",
1664d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1665eef0660aSRandall Stewart cache1, 2 },
1666d95b3509SRandall Stewart /*10*/ { "dtlbmissload", "thresh >= .1",
1667d95b3509SRandall Stewart "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1668eef0660aSRandall Stewart dtlb_missload, 3 },
1669d95b3509SRandall Stewart /*11*/ { "dtlbmissstore", "thresh >= .05",
1670d95b3509SRandall Stewart "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1671eef0660aSRandall Stewart dtlb_missstore, 3 },
1672d95b3509SRandall Stewart /*12*/ { "frontendstall", "thresh >= .15",
1673d95b3509SRandall Stewart "pmcstat -s IDQ_UOPS_NOT_DELIVERED.CORE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1674eef0660aSRandall Stewart frontendstall, 2 },
1675d95b3509SRandall Stewart /*13*/ { "clears", "thresh >= .02",
1676d95b3509SRandall Stewart "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1677eef0660aSRandall Stewart clears, 4 },
1678d95b3509SRandall Stewart /*14*/ { "microassist", "thresh >= .05",
1679d95b3509SRandall Stewart "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1680eef0660aSRandall Stewart microassist, 2 },
1681d95b3509SRandall Stewart /*15*/ { "aliasing_4k", "thresh >= .1",
1682d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1683eef0660aSRandall Stewart aliasing, 2 },
1684d95b3509SRandall Stewart /*16*/ { "fpassist", "look for a excessive value",
1685d95b3509SRandall Stewart "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
1686eef0660aSRandall Stewart fpassists, 2 },
1687d95b3509SRandall Stewart /*17*/ { "otherassistavx", "look for a excessive value",
1688d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1689eef0660aSRandall Stewart otherassistavx, 2},
1690d95b3509SRandall Stewart /*18*/ { "otherassistsse", "look for a excessive value",
1691d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1692eef0660aSRandall Stewart otherassistsse, 2 },
1693d95b3509SRandall Stewart /*19*/ { "eff1", "thresh < .9",
1694d95b3509SRandall Stewart "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1695eef0660aSRandall Stewart efficiency1, 2 },
1696d95b3509SRandall Stewart /*20*/ { "eff2", "thresh > 1.0",
1697d95b3509SRandall Stewart "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1698eef0660aSRandall Stewart efficiency2, 2 },
1699d95b3509SRandall Stewart };
1700d95b3509SRandall Stewart
1701d95b3509SRandall Stewart
1702d95b3509SRandall Stewart #define IVY_BRIDGE_COUNT 21
1703d95b3509SRandall Stewart static struct cpu_entry ivy_bridge[IVY_BRIDGE_COUNT] = {
1704d95b3509SRandall Stewart /*1*/ { "eff1", "thresh < .75",
1705d95b3509SRandall Stewart "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1706eef0660aSRandall Stewart efficiency1, 2 },
1707d95b3509SRandall Stewart /*2*/ { "eff2", "thresh > 1.0",
1708d95b3509SRandall Stewart "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1709eef0660aSRandall Stewart efficiency2, 2 },
1710d95b3509SRandall Stewart /*3*/ { "itlbmiss", "thresh > .05",
1711d95b3509SRandall Stewart "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1712eef0660aSRandall Stewart itlb_miss, 2 },
1713d95b3509SRandall Stewart /*4*/ { "icachemiss", "thresh > .05",
1714d95b3509SRandall Stewart "pmcstat -s ICACHE.IFETCH_STALL -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1715eef0660aSRandall Stewart icache_miss, 3 },
1716d95b3509SRandall Stewart /*5*/ { "lcpstall", "thresh > .05",
1717d95b3509SRandall Stewart "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1718eef0660aSRandall Stewart lcp_stall, 2 },
1719d95b3509SRandall Stewart /*6*/ { "cache1", "thresh >= .2",
1720d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1721eef0660aSRandall Stewart cache1ib, 2 },
1722d95b3509SRandall Stewart /*7*/ { "cache2", "thresh >= .2",
1723d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1724eef0660aSRandall Stewart cache2ib, 2 },
1725d95b3509SRandall Stewart /*8*/ { "contested", "thresh >= .05",
1726d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1727eef0660aSRandall Stewart contested, 2 },
1728d95b3509SRandall Stewart /*9*/ { "datashare", "thresh >= .05",
1729d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1730eef0660aSRandall Stewart datasharing, 2 },
1731d95b3509SRandall Stewart /*10*/ { "blockstorefwd", "thresh >= .05",
1732d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1733eef0660aSRandall Stewart blockstoreforward, 2 },
1734d95b3509SRandall Stewart /*11*/ { "splitload", "thresh >= .1",
1735d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1",
1736eef0660aSRandall Stewart splitloadib, 4 },
1737d95b3509SRandall Stewart /*12*/ { "splitstore", "thresh >= .01",
1738eef0660aSRandall Stewart "pmcstat -s MEM_UOPS_RETIRED.SPLIT_STORES -s MEM_UOPS_RETIRED.ALL_STORES -w 1",
1739eef0660aSRandall Stewart splitstore, 2 },
1740d95b3509SRandall Stewart /*13*/ { "aliasing_4k", "thresh >= .1",
1741d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1742eef0660aSRandall Stewart aliasing, 2 },
1743d95b3509SRandall Stewart /*14*/ { "dtlbmissload", "thresh >= .1",
1744d95b3509SRandall Stewart "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1745eef0660aSRandall Stewart dtlb_missload , 3},
1746d95b3509SRandall Stewart /*15*/ { "dtlbmissstore", "thresh >= .05",
1747d95b3509SRandall Stewart "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1748eef0660aSRandall Stewart dtlb_missstore, 3 },
1749d95b3509SRandall Stewart /*16*/ { "br_miss", "thresh >= .2",
1750d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",
1751eef0660aSRandall Stewart br_mispredictib, 8 },
1752d95b3509SRandall Stewart /*17*/ { "clears", "thresh >= .02",
1753d95b3509SRandall Stewart "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1754eef0660aSRandall Stewart clears, 4 },
1755d95b3509SRandall Stewart /*18*/ { "microassist", "thresh >= .05",
1756d95b3509SRandall Stewart "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1757eef0660aSRandall Stewart microassist, 2 },
1758d95b3509SRandall Stewart /*19*/ { "fpassist", "look for a excessive value",
1759d95b3509SRandall Stewart "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
1760eef0660aSRandall Stewart fpassists, 2 },
1761d95b3509SRandall Stewart /*20*/ { "otherassistavx", "look for a excessive value",
1762d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1763eef0660aSRandall Stewart otherassistavx , 2},
1764d95b3509SRandall Stewart /*21*/ { "otherassistsse", "look for a excessive value",
1765d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1766eef0660aSRandall Stewart otherassistsse, 2 },
1767d95b3509SRandall Stewart };
1768d95b3509SRandall Stewart
1769d95b3509SRandall Stewart #define HASWELL_COUNT 20
1770d95b3509SRandall Stewart static struct cpu_entry haswell[HASWELL_COUNT] = {
1771d95b3509SRandall Stewart /*1*/ { "eff1", "thresh < .75",
1772d95b3509SRandall Stewart "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1773eef0660aSRandall Stewart efficiency1, 2 },
1774d95b3509SRandall Stewart /*2*/ { "eff2", "thresh > 1.0",
1775d95b3509SRandall Stewart "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1776eef0660aSRandall Stewart efficiency2, 2 },
1777d95b3509SRandall Stewart /*3*/ { "itlbmiss", "thresh > .05",
1778d95b3509SRandall Stewart "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1779eef0660aSRandall Stewart itlb_miss, 2 },
1780d95b3509SRandall Stewart /*4*/ { "icachemiss", "thresh > .05",
1781eef0660aSRandall Stewart "pmcstat -s ICACHE.MISSES -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1782eef0660aSRandall Stewart icache_miss_has, 2 },
1783d95b3509SRandall Stewart /*5*/ { "lcpstall", "thresh > .05",
1784d95b3509SRandall Stewart "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1785eef0660aSRandall Stewart lcp_stall, 2 },
1786d95b3509SRandall Stewart /*6*/ { "cache1", "thresh >= .2",
1787d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1788eef0660aSRandall Stewart cache1ib, 2 },
1789d95b3509SRandall Stewart /*7*/ { "cache2", "thresh >= .2",
1790d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1791eef0660aSRandall Stewart cache2has, 4 },
1792d95b3509SRandall Stewart /*8*/ { "contested", "thresh >= .05",
1793d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1794eef0660aSRandall Stewart contested_has, 2 },
1795d95b3509SRandall Stewart /*9*/ { "datashare", "thresh >= .05",
1796d95b3509SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1797eef0660aSRandall Stewart datasharing_has, 2 },
1798d95b3509SRandall Stewart /*10*/ { "blockstorefwd", "thresh >= .05",
1799d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1800eef0660aSRandall Stewart blockstoreforward, 2 },
1801d95b3509SRandall Stewart /*11*/ { "splitload", "thresh >= .1",
1802eef0660aSRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOPS_RETIRED.SPLIT_LOADS -w 1",
1803eef0660aSRandall Stewart splitload , 2},
1804d95b3509SRandall Stewart /*12*/ { "splitstore", "thresh >= .01",
1805eef0660aSRandall Stewart "pmcstat -s MEM_UOPS_RETIRED.SPLIT_STORES -s MEM_UOPS_RETIRED.ALL_STORES -w 1",
1806eef0660aSRandall Stewart splitstore, 2 },
1807d95b3509SRandall Stewart /*13*/ { "aliasing_4k", "thresh >= .1",
1808d95b3509SRandall Stewart "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1809eef0660aSRandall Stewart aliasing, 2 },
1810d95b3509SRandall Stewart /*14*/ { "dtlbmissload", "thresh >= .1",
1811d95b3509SRandall Stewart "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1812eef0660aSRandall Stewart dtlb_missload, 3 },
1813d95b3509SRandall Stewart /*15*/ { "br_miss", "thresh >= .2",
1814d95b3509SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1",
1815eef0660aSRandall Stewart br_mispredict, 2 },
1816d95b3509SRandall Stewart /*16*/ { "clears", "thresh >= .02",
1817d95b3509SRandall Stewart "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1818eef0660aSRandall Stewart clears, 4 },
1819d95b3509SRandall Stewart /*17*/ { "microassist", "thresh >= .05",
1820d95b3509SRandall Stewart "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1821eef0660aSRandall Stewart microassist, 2 },
1822d95b3509SRandall Stewart /*18*/ { "fpassist", "look for a excessive value",
1823d95b3509SRandall Stewart "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
1824eef0660aSRandall Stewart fpassists, 2 },
1825d95b3509SRandall Stewart /*19*/ { "otherassistavx", "look for a excessive value",
1826d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1827eef0660aSRandall Stewart otherassistavx, 2 },
1828d95b3509SRandall Stewart /*20*/ { "otherassistsse", "look for a excessive value",
1829d95b3509SRandall Stewart "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1830eef0660aSRandall Stewart otherassistsse, 2 },
1831d95b3509SRandall Stewart };
1832d95b3509SRandall Stewart
1833d95b3509SRandall Stewart
1834d95b3509SRandall Stewart static void
explain_name_broad(const char * name)1835ade40db3SRandall Stewart explain_name_broad(const char *name)
1836ade40db3SRandall Stewart {
1837ade40db3SRandall Stewart const char *mythresh;
1838ade40db3SRandall Stewart if (strcmp(name, "eff1") == 0) {
1839ade40db3SRandall Stewart printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n");
1840ade40db3SRandall Stewart mythresh = "thresh < .75";
1841ade40db3SRandall Stewart } else if (strcmp(name, "eff2") == 0) {
1842ade40db3SRandall Stewart printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n");
1843ade40db3SRandall Stewart mythresh = "thresh > 1.0";
1844ade40db3SRandall Stewart } else if (strcmp(name, "itlbmiss") == 0) {
1845ade40db3SRandall Stewart printf("Examine (7 * ITLB_MISSES_STLB_HIT_4K + ITLB_MISSES.WALK_DURATION)/ CPU_CLK_UNHALTED.THREAD_P\n");
1846ade40db3SRandall Stewart mythresh = "thresh > .05";
1847ade40db3SRandall Stewart } else if (strcmp(name, "icachemiss") == 0) {
1848eef0660aSRandall Stewart printf("Examine ( 36.0 * ICACHE.MISSES)/ CPU_CLK_UNHALTED.THREAD_P ??? may not be right \n");
1849ade40db3SRandall Stewart mythresh = "thresh > .05";
1850ade40db3SRandall Stewart } else if (strcmp(name, "lcpstall") == 0) {
1851ade40db3SRandall Stewart printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n");
1852ade40db3SRandall Stewart mythresh = "thresh > .05";
1853ade40db3SRandall Stewart } else if (strcmp(name, "cache1") == 0) {
1854ade40db3SRandall Stewart printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n");
1855ade40db3SRandall Stewart mythresh = "thresh >= .1";
1856ade40db3SRandall Stewart } else if (strcmp(name, "cache2") == 0) {
1857ade40db3SRandall Stewart printf("Examine (36.0 * MEM_LOAD_UOPS_RETIRED.L3_HIT / CPU_CLK_UNHALTED.THREAD_P)\n");
1858ade40db3SRandall Stewart mythresh = "thresh >= .2";
1859ade40db3SRandall Stewart } else if (strcmp(name, "contested") == 0) {
1860ade40db3SRandall Stewart printf("Examine ((MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) + MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS)/ CPU_CLK_UNHALTED.THREAD_P\n");
1861ade40db3SRandall Stewart mythresh = "thresh >= .05";
1862ade40db3SRandall Stewart } else if (strcmp(name, "datashare") == 0) {
1863ade40db3SRandall Stewart printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 72)/CPU_CLK_UNHALTED.THREAD_P\n");
1864ade40db3SRandall Stewart mythresh = "thresh > .05";
1865ade40db3SRandall Stewart } else if (strcmp(name, "blockstorefwd") == 0) {
1866ade40db3SRandall Stewart printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
1867ade40db3SRandall Stewart mythresh = "thresh >= .05";
1868ade40db3SRandall Stewart } else if (strcmp(name, "aliasing_4k") == 0) {
1869ade40db3SRandall Stewart printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 7) / CPU_CLK_UNHALTED.THREAD_P\n");
1870ade40db3SRandall Stewart mythresh = "thresh >= .1";
1871ade40db3SRandall Stewart } else if (strcmp(name, "dtlbmissload") == 0) {
1872ade40db3SRandall Stewart printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n");
1873ade40db3SRandall Stewart printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
1874ade40db3SRandall Stewart mythresh = "thresh >= .1";
1875ade40db3SRandall Stewart
1876ade40db3SRandall Stewart } else if (strcmp(name, "br_miss") == 0) {
1877ade40db3SRandall Stewart printf("Examine BR_MISP_RETIRED.ALL_BRANCHS_PS / (BR_MISP_RETIED.ALL_BRANCHES_PS + MACHINE_CLEARS.COUNT) *\n");
1878ade40db3SRandall Stewart printf(" (UOPS_ISSUEDF.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) /\n");
1879ade40db3SRandall Stewart printf("CPU_CLK_UNHALTED.THREAD * 4)\n");
1880ade40db3SRandall Stewart mythresh = "thresh >= .2";
1881ade40db3SRandall Stewart } else if (strcmp(name, "clears") == 0) {
1882ade40db3SRandall Stewart printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n");
1883ade40db3SRandall Stewart printf(" MACHINE_CLEARS.SMC + \n");
1884ade40db3SRandall Stewart printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n");
1885ade40db3SRandall Stewart mythresh = "thresh >= .02";
1886ade40db3SRandall Stewart } else if (strcmp(name, "fpassist") == 0) {
1887ade40db3SRandall Stewart printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n");
1888ade40db3SRandall Stewart mythresh = "look for a excessive value";
1889ade40db3SRandall Stewart } else if (strcmp(name, "otherassistavx") == 0) {
1890ade40db3SRandall Stewart printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
1891ade40db3SRandall Stewart mythresh = "look for a excessive value";
1892ade40db3SRandall Stewart } else if (strcmp(name, "microassist") == 0) {
1893ade40db3SRandall Stewart printf("Examine (UOPS_RETIRED.RETIRE_SLOTS/UOPS_ISSUED.ANY) * (IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n");
1894ade40db3SRandall Stewart printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n");
1895ade40db3SRandall Stewart mythresh = "thresh >= .05";
1896ade40db3SRandall Stewart } else {
1897ade40db3SRandall Stewart printf("Unknown name:%s\n", name);
1898ade40db3SRandall Stewart mythresh = "unknown entry";
1899ade40db3SRandall Stewart }
1900ade40db3SRandall Stewart printf("If the value printed is %s we may have the ability to improve performance\n", mythresh);
1901ade40db3SRandall Stewart }
1902ade40db3SRandall Stewart
1903ade40db3SRandall Stewart
1904ade40db3SRandall Stewart #define BROADWELL_COUNT 17
1905ade40db3SRandall Stewart static struct cpu_entry broadwell[BROADWELL_COUNT] = {
1906ade40db3SRandall Stewart /*1*/ { "eff1", "thresh < .75",
1907ade40db3SRandall Stewart "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1908eef0660aSRandall Stewart efficiency1, 2 },
1909ade40db3SRandall Stewart /*2*/ { "eff2", "thresh > 1.0",
1910ade40db3SRandall Stewart "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1911eef0660aSRandall Stewart efficiency2, 2 },
1912ade40db3SRandall Stewart /*3*/ { "itlbmiss", "thresh > .05",
1913ade40db3SRandall Stewart "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -s ITLB_MISSES.STLB_HIT_4K -w 1",
1914eef0660aSRandall Stewart itlb_miss_broad, 3 },
1915ade40db3SRandall Stewart /*4*/ { "icachemiss", "thresh > .05",
1916eef0660aSRandall Stewart "pmcstat -s ICACHE.MISSES -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1917eef0660aSRandall Stewart icache_miss_has, 2 },
1918ade40db3SRandall Stewart /*5*/ { "lcpstall", "thresh > .05",
1919ade40db3SRandall Stewart "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1920eef0660aSRandall Stewart lcp_stall, 2 },
1921ade40db3SRandall Stewart /*6*/ { "cache1", "thresh >= .1",
1922ade40db3SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_RETIRED.L3_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1923eef0660aSRandall Stewart cache1broad, 2 },
1924ade40db3SRandall Stewart /*7*/ { "cache2", "thresh >= .2",
1925ade40db3SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_RETIRED.L3_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1926eef0660aSRandall Stewart cache2broad, 2 },
1927ade40db3SRandall Stewart /*8*/ { "contested", "thresh >= .05",
1928ade40db3SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS -w 1",
1929eef0660aSRandall Stewart contestedbroad, 2 },
1930ade40db3SRandall Stewart /*9*/ { "datashare", "thresh >= .05",
1931ade40db3SRandall Stewart "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1932eef0660aSRandall Stewart datasharing_has, 2 },
1933ade40db3SRandall Stewart /*10*/ { "blockstorefwd", "thresh >= .05",
1934ade40db3SRandall Stewart "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1935eef0660aSRandall Stewart blockstoreforward, 2 },
1936ade40db3SRandall Stewart /*11*/ { "aliasing_4k", "thresh >= .1",
1937ade40db3SRandall Stewart "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1938eef0660aSRandall Stewart aliasing_broad, 2 },
1939ade40db3SRandall Stewart /*12*/ { "dtlbmissload", "thresh >= .1",
1940eef0660aSRandall Stewart "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT_4K -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1941eef0660aSRandall Stewart dtlb_missload, 3 },
1942ade40db3SRandall Stewart /*13*/ { "br_miss", "thresh >= .2",
1943ade40db3SRandall Stewart "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.CYCLES -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",
1944eef0660aSRandall Stewart br_mispredict_broad, 7 },
1945ade40db3SRandall Stewart /*14*/ { "clears", "thresh >= .02",
1946ade40db3SRandall Stewart "pmcstat -s MACHINE_CLEARS.CYCLES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1947eef0660aSRandall Stewart clears_broad, 5 },
1948ade40db3SRandall Stewart /*15*/ { "fpassist", "look for a excessive value",
1949ade40db3SRandall Stewart "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
1950eef0660aSRandall Stewart fpassists, 2 },
1951ade40db3SRandall Stewart /*16*/ { "otherassistavx", "look for a excessive value",
1952ade40db3SRandall Stewart "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
1953eef0660aSRandall Stewart otherassistavx, 2 },
1954ade40db3SRandall Stewart /*17*/ { "microassist", "thresh >= .2",
1955ade40db3SRandall Stewart "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -w 1",
1956eef0660aSRandall Stewart microassist_broad, 4 },
1957ade40db3SRandall Stewart };
1958ade40db3SRandall Stewart
1959eef0660aSRandall Stewart
1960ade40db3SRandall Stewart static void
set_sandybridge(void)1961d95b3509SRandall Stewart set_sandybridge(void)
1962d95b3509SRandall Stewart {
1963d95b3509SRandall Stewart strcpy(the_cpu.cputype, "SandyBridge PMC");
1964d95b3509SRandall Stewart the_cpu.number = SANDY_BRIDGE_COUNT;
1965d95b3509SRandall Stewart the_cpu.ents = sandy_bridge;
1966d95b3509SRandall Stewart the_cpu.explain = explain_name_sb;
1967d95b3509SRandall Stewart }
1968d95b3509SRandall Stewart
1969d95b3509SRandall Stewart static void
set_ivybridge(void)1970d95b3509SRandall Stewart set_ivybridge(void)
1971d95b3509SRandall Stewart {
1972d95b3509SRandall Stewart strcpy(the_cpu.cputype, "IvyBridge PMC");
1973d95b3509SRandall Stewart the_cpu.number = IVY_BRIDGE_COUNT;
1974d95b3509SRandall Stewart the_cpu.ents = ivy_bridge;
1975d95b3509SRandall Stewart the_cpu.explain = explain_name_ib;
1976d95b3509SRandall Stewart }
1977d95b3509SRandall Stewart
1978d95b3509SRandall Stewart
1979d95b3509SRandall Stewart static void
set_haswell(void)1980d95b3509SRandall Stewart set_haswell(void)
1981d95b3509SRandall Stewart {
1982d95b3509SRandall Stewart strcpy(the_cpu.cputype, "HASWELL PMC");
1983d95b3509SRandall Stewart the_cpu.number = HASWELL_COUNT;
1984d95b3509SRandall Stewart the_cpu.ents = haswell;
1985d95b3509SRandall Stewart the_cpu.explain = explain_name_has;
1986d95b3509SRandall Stewart }
1987d95b3509SRandall Stewart
1988eef0660aSRandall Stewart
1989d95b3509SRandall Stewart static void
set_broadwell(void)1990ade40db3SRandall Stewart set_broadwell(void)
1991ade40db3SRandall Stewart {
1992ade40db3SRandall Stewart strcpy(the_cpu.cputype, "HASWELL PMC");
1993ade40db3SRandall Stewart the_cpu.number = BROADWELL_COUNT;
1994ade40db3SRandall Stewart the_cpu.ents = broadwell;
1995ade40db3SRandall Stewart the_cpu.explain = explain_name_broad;
1996ade40db3SRandall Stewart }
1997ade40db3SRandall Stewart
1998eef0660aSRandall Stewart
1999eef0660aSRandall Stewart static int
set_expression(const char * name)2000eef0660aSRandall Stewart set_expression(const char *name)
2001d95b3509SRandall Stewart {
2002d95b3509SRandall Stewart int found = 0, i;
2003d95b3509SRandall Stewart for(i=0 ; i< the_cpu.number; i++) {
2004d95b3509SRandall Stewart if (strcmp(name, the_cpu.ents[i].name) == 0) {
2005d95b3509SRandall Stewart found = 1;
2006d95b3509SRandall Stewart expression = the_cpu.ents[i].func;
2007d95b3509SRandall Stewart command = the_cpu.ents[i].command;
2008d95b3509SRandall Stewart threshold = the_cpu.ents[i].thresh;
2009eef0660aSRandall Stewart if (the_cpu.ents[i].counters_required > max_pmc_counters) {
2010eef0660aSRandall Stewart printf("Test %s requires that the CPU have %d counters and this CPU has only %d\n",
2011eef0660aSRandall Stewart the_cpu.ents[i].name,
2012eef0660aSRandall Stewart the_cpu.ents[i].counters_required, max_pmc_counters);
2013eef0660aSRandall Stewart printf("Sorry this test can not be run\n");
2014eef0660aSRandall Stewart if (run_all == 0) {
2015eef0660aSRandall Stewart exit(-1);
2016eef0660aSRandall Stewart } else {
2017eef0660aSRandall Stewart return(-1);
2018eef0660aSRandall Stewart }
2019eef0660aSRandall Stewart }
2020d95b3509SRandall Stewart break;
2021d95b3509SRandall Stewart }
2022d95b3509SRandall Stewart }
2023d95b3509SRandall Stewart if (!found) {
2024d95b3509SRandall Stewart printf("For CPU type %s we have no expression:%s\n",
2025d95b3509SRandall Stewart the_cpu.cputype, name);
2026d95b3509SRandall Stewart exit(-1);
2027d95b3509SRandall Stewart }
2028eef0660aSRandall Stewart return(0);
2029d95b3509SRandall Stewart }
2030d95b3509SRandall Stewart
2031eef0660aSRandall Stewart
2032eef0660aSRandall Stewart
2033eef0660aSRandall Stewart
2034eef0660aSRandall Stewart
2035d95b3509SRandall Stewart static int
validate_expression(char * name)2036d95b3509SRandall Stewart validate_expression(char *name)
2037d95b3509SRandall Stewart {
2038d95b3509SRandall Stewart int i, found;
2039d95b3509SRandall Stewart
2040d95b3509SRandall Stewart found = 0;
2041d95b3509SRandall Stewart for(i=0 ; i< the_cpu.number; i++) {
2042d95b3509SRandall Stewart if (strcmp(name, the_cpu.ents[i].name) == 0) {
2043d95b3509SRandall Stewart found = 1;
2044d95b3509SRandall Stewart break;
2045d95b3509SRandall Stewart }
2046d95b3509SRandall Stewart }
2047d95b3509SRandall Stewart if (!found) {
2048d95b3509SRandall Stewart return(-1);
2049d95b3509SRandall Stewart }
2050d95b3509SRandall Stewart return (0);
2051d95b3509SRandall Stewart }
2052d95b3509SRandall Stewart
2053d95b3509SRandall Stewart static void
do_expression(struct counters * cpu,int pos)2054d95b3509SRandall Stewart do_expression(struct counters *cpu, int pos)
2055d95b3509SRandall Stewart {
2056d95b3509SRandall Stewart if (expression == NULL)
2057d95b3509SRandall Stewart return;
2058d95b3509SRandall Stewart (*expression)(cpu, pos);
2059d95b3509SRandall Stewart }
2060d95b3509SRandall Stewart
2061d95b3509SRandall Stewart static void
process_header(int idx,char * p)2062d95b3509SRandall Stewart process_header(int idx, char *p)
2063d95b3509SRandall Stewart {
2064d95b3509SRandall Stewart struct counters *up;
2065d95b3509SRandall Stewart int i, len, nlen;
2066d95b3509SRandall Stewart /*
2067eef0660aSRandall Stewart * Given header element idx, at p in
2068eef0660aSRandall Stewart * form 's/NN/nameof'
2069eef0660aSRandall Stewart * process the entry to pull out the name and
2070eef0660aSRandall Stewart * the CPU number.
2071d95b3509SRandall Stewart */
2072d95b3509SRandall Stewart if (strncmp(p, "s/", 2)) {
2073d95b3509SRandall Stewart printf("Check -- invalid header no s/ in %s\n",
2074d95b3509SRandall Stewart p);
2075d95b3509SRandall Stewart return;
2076d95b3509SRandall Stewart }
2077d95b3509SRandall Stewart up = &cnts[idx];
2078d95b3509SRandall Stewart up->cpu = strtol(&p[2], NULL, 10);
2079d95b3509SRandall Stewart len = strlen(p);
2080d95b3509SRandall Stewart for (i=2; i<len; i++) {
2081d95b3509SRandall Stewart if (p[i] == '/') {
2082d95b3509SRandall Stewart nlen = strlen(&p[(i+1)]);
2083d95b3509SRandall Stewart if (nlen < (MAX_NLEN-1)) {
2084d95b3509SRandall Stewart strcpy(up->counter_name, &p[(i+1)]);
2085d95b3509SRandall Stewart } else {
2086d95b3509SRandall Stewart strncpy(up->counter_name, &p[(i+1)], (MAX_NLEN-1));
2087d95b3509SRandall Stewart }
2088d95b3509SRandall Stewart }
2089d95b3509SRandall Stewart }
2090d95b3509SRandall Stewart }
2091d95b3509SRandall Stewart
2092d95b3509SRandall Stewart static void
build_counters_from_header(FILE * io)2093d95b3509SRandall Stewart build_counters_from_header(FILE *io)
2094d95b3509SRandall Stewart {
2095d95b3509SRandall Stewart char buffer[8192], *p;
2096d95b3509SRandall Stewart int i, len, cnt;
2097d95b3509SRandall Stewart size_t mlen;
2098d95b3509SRandall Stewart
2099eef0660aSRandall Stewart /* We have a new start, lets
2100eef0660aSRandall Stewart * setup our headers and cpus.
2101d95b3509SRandall Stewart */
2102d95b3509SRandall Stewart if (fgets(buffer, sizeof(buffer), io) == NULL) {
2103d95b3509SRandall Stewart printf("First line can't be read from file err:%d\n", errno);
2104d95b3509SRandall Stewart return;
2105d95b3509SRandall Stewart }
2106d95b3509SRandall Stewart /*
2107eef0660aSRandall Stewart * Ok output is an array of counters. Once
2108eef0660aSRandall Stewart * we start to read the values in we must
2109eef0660aSRandall Stewart * put them in there slot to match there CPU and
2110eef0660aSRandall Stewart * counter being updated. We create a mass array
2111eef0660aSRandall Stewart * of the counters, filling in the CPU and
2112eef0660aSRandall Stewart * counter name.
2113d95b3509SRandall Stewart */
2114d95b3509SRandall Stewart /* How many do we get? */
2115d95b3509SRandall Stewart len = strlen(buffer);
2116d95b3509SRandall Stewart for (i=0, cnt=0; i<len; i++) {
2117d95b3509SRandall Stewart if (strncmp(&buffer[i], "s/", 2) == 0) {
2118d95b3509SRandall Stewart cnt++;
2119d95b3509SRandall Stewart for(;i<len;i++) {
2120d95b3509SRandall Stewart if (buffer[i] == ' ')
2121d95b3509SRandall Stewart break;
2122d95b3509SRandall Stewart }
2123d95b3509SRandall Stewart }
2124d95b3509SRandall Stewart }
2125d95b3509SRandall Stewart mlen = sizeof(struct counters) * cnt;
2126d95b3509SRandall Stewart cnts = malloc(mlen);
2127d95b3509SRandall Stewart ncnts = cnt;
2128d95b3509SRandall Stewart if (cnts == NULL) {
2129d95b3509SRandall Stewart printf("No memory err:%d\n", errno);
2130d95b3509SRandall Stewart return;
2131d95b3509SRandall Stewart }
2132d95b3509SRandall Stewart memset(cnts, 0, mlen);
2133d95b3509SRandall Stewart for (i=0, cnt=0; i<len; i++) {
2134d95b3509SRandall Stewart if (strncmp(&buffer[i], "s/", 2) == 0) {
2135d95b3509SRandall Stewart p = &buffer[i];
2136d95b3509SRandall Stewart for(;i<len;i++) {
2137d95b3509SRandall Stewart if (buffer[i] == ' ') {
2138d95b3509SRandall Stewart buffer[i] = 0;
2139d95b3509SRandall Stewart break;
2140d95b3509SRandall Stewart }
2141d95b3509SRandall Stewart }
2142d95b3509SRandall Stewart process_header(cnt, p);
2143d95b3509SRandall Stewart cnt++;
2144d95b3509SRandall Stewart }
2145d95b3509SRandall Stewart }
2146d95b3509SRandall Stewart if (verbose)
2147d95b3509SRandall Stewart printf("We have %d entries\n", cnt);
2148d95b3509SRandall Stewart }
2149d95b3509SRandall Stewart extern int max_to_collect;
2150d95b3509SRandall Stewart int max_to_collect = MAX_COUNTER_SLOTS;
2151d95b3509SRandall Stewart
2152d95b3509SRandall Stewart static int
read_a_line(FILE * io)2153d95b3509SRandall Stewart read_a_line(FILE *io)
2154d95b3509SRandall Stewart {
2155d95b3509SRandall Stewart char buffer[8192], *p, *stop;
2156d95b3509SRandall Stewart int pos, i;
2157d95b3509SRandall Stewart
2158d95b3509SRandall Stewart if (fgets(buffer, sizeof(buffer), io) == NULL) {
2159d95b3509SRandall Stewart return(0);
2160d95b3509SRandall Stewart }
2161d95b3509SRandall Stewart p = buffer;
2162d95b3509SRandall Stewart for (i=0; i<ncnts; i++) {
2163d95b3509SRandall Stewart pos = cnts[i].pos;
2164d95b3509SRandall Stewart cnts[i].vals[pos] = strtol(p, &stop, 0);
2165d95b3509SRandall Stewart cnts[i].pos++;
2166d95b3509SRandall Stewart cnts[i].sum += cnts[i].vals[pos];
2167d95b3509SRandall Stewart p = stop;
2168d95b3509SRandall Stewart }
2169d95b3509SRandall Stewart return (1);
2170d95b3509SRandall Stewart }
2171d95b3509SRandall Stewart
2172d95b3509SRandall Stewart extern int cpu_count_out;
2173d95b3509SRandall Stewart int cpu_count_out=0;
2174d95b3509SRandall Stewart
2175d95b3509SRandall Stewart static void
print_header(void)2176d95b3509SRandall Stewart print_header(void)
2177d95b3509SRandall Stewart {
2178d95b3509SRandall Stewart int i, cnt, printed_cnt;
2179d95b3509SRandall Stewart
2180d95b3509SRandall Stewart printf("*********************************\n");
2181d95b3509SRandall Stewart for(i=0, cnt=0; i<MAX_CPU; i++) {
2182d95b3509SRandall Stewart if (glob_cpu[i]) {
2183d95b3509SRandall Stewart cnt++;
2184d95b3509SRandall Stewart }
2185d95b3509SRandall Stewart }
2186d95b3509SRandall Stewart cpu_count_out = cnt;
2187d95b3509SRandall Stewart for(i=0, printed_cnt=0; i<MAX_CPU; i++) {
2188d95b3509SRandall Stewart if (glob_cpu[i]) {
2189d95b3509SRandall Stewart printf("CPU%d", i);
2190d95b3509SRandall Stewart printed_cnt++;
2191d95b3509SRandall Stewart }
2192d95b3509SRandall Stewart if (printed_cnt == cnt) {
2193d95b3509SRandall Stewart printf("\n");
2194d95b3509SRandall Stewart break;
2195d95b3509SRandall Stewart } else {
2196d95b3509SRandall Stewart printf("\t");
2197d95b3509SRandall Stewart }
2198d95b3509SRandall Stewart }
2199d95b3509SRandall Stewart }
2200d95b3509SRandall Stewart
2201d95b3509SRandall Stewart static void
lace_cpus_together(void)2202d95b3509SRandall Stewart lace_cpus_together(void)
2203d95b3509SRandall Stewart {
2204d95b3509SRandall Stewart int i, j, lace_cpu;
2205d95b3509SRandall Stewart struct counters *cpat, *at;
2206d95b3509SRandall Stewart
2207d95b3509SRandall Stewart for(i=0; i<ncnts; i++) {
2208d95b3509SRandall Stewart cpat = &cnts[i];
2209d95b3509SRandall Stewart if (cpat->next_cpu) {
2210d95b3509SRandall Stewart /* Already laced in */
2211d95b3509SRandall Stewart continue;
2212d95b3509SRandall Stewart }
2213d95b3509SRandall Stewart lace_cpu = cpat->cpu;
2214d95b3509SRandall Stewart if (lace_cpu >= MAX_CPU) {
2215d95b3509SRandall Stewart printf("CPU %d to big\n", lace_cpu);
2216d95b3509SRandall Stewart continue;
2217d95b3509SRandall Stewart }
2218d95b3509SRandall Stewart if (glob_cpu[lace_cpu] == NULL) {
2219d95b3509SRandall Stewart glob_cpu[lace_cpu] = cpat;
2220d95b3509SRandall Stewart } else {
2221d95b3509SRandall Stewart /* Already processed this cpu */
2222d95b3509SRandall Stewart continue;
2223d95b3509SRandall Stewart }
2224d95b3509SRandall Stewart /* Ok look forward for cpu->cpu and link in */
2225d95b3509SRandall Stewart for(j=(i+1); j<ncnts; j++) {
2226d95b3509SRandall Stewart at = &cnts[j];
2227d95b3509SRandall Stewart if (at->next_cpu) {
2228d95b3509SRandall Stewart continue;
2229d95b3509SRandall Stewart }
2230d95b3509SRandall Stewart if (at->cpu == lace_cpu) {
2231d95b3509SRandall Stewart /* Found one */
2232d95b3509SRandall Stewart cpat->next_cpu = at;
2233d95b3509SRandall Stewart cpat = at;
2234d95b3509SRandall Stewart }
2235d95b3509SRandall Stewart }
2236d95b3509SRandall Stewart }
2237d95b3509SRandall Stewart }
2238d95b3509SRandall Stewart
2239d95b3509SRandall Stewart
2240d95b3509SRandall Stewart static void
process_file(char * filename)2241d95b3509SRandall Stewart process_file(char *filename)
2242d95b3509SRandall Stewart {
2243d95b3509SRandall Stewart FILE *io;
2244d95b3509SRandall Stewart int i;
2245d95b3509SRandall Stewart int line_at, not_done;
2246d95b3509SRandall Stewart pid_t pid_of_command=0;
2247d95b3509SRandall Stewart
2248d95b3509SRandall Stewart if (filename == NULL) {
2249d95b3509SRandall Stewart io = my_popen(command, "r", &pid_of_command);
2250bffefaf3Ssebastien.bini if (io == NULL) {
2251bffefaf3Ssebastien.bini printf("Can't popen the command %s\n", command);
2252bffefaf3Ssebastien.bini return;
2253bffefaf3Ssebastien.bini }
2254d95b3509SRandall Stewart } else {
2255d95b3509SRandall Stewart io = fopen(filename, "r");
2256d95b3509SRandall Stewart if (io == NULL) {
2257d95b3509SRandall Stewart printf("Can't process file %s err:%d\n",
2258d95b3509SRandall Stewart filename, errno);
2259d95b3509SRandall Stewart return;
2260d95b3509SRandall Stewart }
2261d95b3509SRandall Stewart }
2262d95b3509SRandall Stewart build_counters_from_header(io);
2263d95b3509SRandall Stewart if (cnts == NULL) {
2264d95b3509SRandall Stewart /* Nothing we can do */
2265d95b3509SRandall Stewart printf("Nothing to do -- no counters built\n");
2266bffefaf3Ssebastien.bini if (filename) {
22678a3bbeb2SRandall Stewart fclose(io);
2268bffefaf3Ssebastien.bini } else {
2269bffefaf3Ssebastien.bini my_pclose(io, pid_of_command);
22708a3bbeb2SRandall Stewart }
2271d95b3509SRandall Stewart return;
2272d95b3509SRandall Stewart }
2273d95b3509SRandall Stewart lace_cpus_together();
2274d95b3509SRandall Stewart print_header();
2275d95b3509SRandall Stewart if (verbose) {
2276d95b3509SRandall Stewart for (i=0; i<ncnts; i++) {
2277d95b3509SRandall Stewart printf("Counter:%s cpu:%d index:%d\n",
2278d95b3509SRandall Stewart cnts[i].counter_name,
2279d95b3509SRandall Stewart cnts[i].cpu, i);
2280d95b3509SRandall Stewart }
2281d95b3509SRandall Stewart }
2282d95b3509SRandall Stewart line_at = 0;
2283d95b3509SRandall Stewart not_done = 1;
2284d95b3509SRandall Stewart while(not_done) {
2285d95b3509SRandall Stewart if (read_a_line(io)) {
2286d95b3509SRandall Stewart line_at++;
2287d95b3509SRandall Stewart } else {
2288d95b3509SRandall Stewart break;
2289d95b3509SRandall Stewart }
2290d95b3509SRandall Stewart if (line_at >= max_to_collect) {
2291d95b3509SRandall Stewart not_done = 0;
2292d95b3509SRandall Stewart }
2293d95b3509SRandall Stewart if (filename == NULL) {
2294d95b3509SRandall Stewart int cnt;
2295d95b3509SRandall Stewart /* For the ones we dynamically open we print now */
2296d95b3509SRandall Stewart for(i=0, cnt=0; i<MAX_CPU; i++) {
2297d95b3509SRandall Stewart do_expression(glob_cpu[i], (line_at-1));
2298d95b3509SRandall Stewart cnt++;
2299d95b3509SRandall Stewart if (cnt == cpu_count_out) {
2300d95b3509SRandall Stewart printf("\n");
2301d95b3509SRandall Stewart break;
2302d95b3509SRandall Stewart } else {
2303d95b3509SRandall Stewart printf("\t");
2304d95b3509SRandall Stewart }
2305d95b3509SRandall Stewart }
2306d95b3509SRandall Stewart }
2307d95b3509SRandall Stewart }
2308d95b3509SRandall Stewart if (filename) {
2309d95b3509SRandall Stewart fclose(io);
2310d95b3509SRandall Stewart } else {
2311d95b3509SRandall Stewart my_pclose(io, pid_of_command);
2312d95b3509SRandall Stewart }
2313d95b3509SRandall Stewart }
2314d95b3509SRandall Stewart #if defined(__amd64__)
2315d95b3509SRandall Stewart #define cpuid(in,a,b,c,d)\
2316d95b3509SRandall Stewart asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
2317eef0660aSRandall Stewart
2318eef0660aSRandall Stewart static __inline void
do_cpuid(u_int ax,u_int cx,u_int * p)2319eef0660aSRandall Stewart do_cpuid(u_int ax, u_int cx, u_int *p)
2320eef0660aSRandall Stewart {
2321eef0660aSRandall Stewart __asm __volatile("cpuid"
2322eef0660aSRandall Stewart : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
2323eef0660aSRandall Stewart : "0" (ax), "c" (cx) );
2324eef0660aSRandall Stewart }
2325eef0660aSRandall Stewart
2326d95b3509SRandall Stewart #else
2327d95b3509SRandall Stewart #define cpuid(in, a, b, c, d)
23285dedd797SBryan Drewery #define do_cpuid(ax, cx, p)
2329d95b3509SRandall Stewart #endif
2330d95b3509SRandall Stewart
2331d95b3509SRandall Stewart static void
get_cpuid_set(void)2332d95b3509SRandall Stewart get_cpuid_set(void)
2333d95b3509SRandall Stewart {
2334d95b3509SRandall Stewart unsigned long eax, ebx, ecx, edx;
2335d95b3509SRandall Stewart int model;
2336d95b3509SRandall Stewart pid_t pid_of_command=0;
2337d95b3509SRandall Stewart size_t sz, len;
2338d95b3509SRandall Stewart FILE *io;
2339d95b3509SRandall Stewart char linebuf[1024], *str;
2340eef0660aSRandall Stewart u_int reg[4];
2341d95b3509SRandall Stewart
2342d95b3509SRandall Stewart eax = ebx = ecx = edx = 0;
2343d95b3509SRandall Stewart
2344d95b3509SRandall Stewart cpuid(0, eax, ebx, ecx, edx);
2345d95b3509SRandall Stewart if (ebx == 0x68747541) {
2346d95b3509SRandall Stewart printf("AMD processors are not supported by this program\n");
2347d95b3509SRandall Stewart printf("Sorry\n");
2348d95b3509SRandall Stewart exit(0);
2349d95b3509SRandall Stewart } else if (ebx == 0x6972794) {
2350d95b3509SRandall Stewart printf("Cyrix processors are not supported by this program\n");
2351d95b3509SRandall Stewart printf("Sorry\n");
2352d95b3509SRandall Stewart exit(0);
2353d95b3509SRandall Stewart } else if (ebx == 0x756e6547) {
2354d95b3509SRandall Stewart printf("Genuine Intel\n");
2355d95b3509SRandall Stewart } else {
2356d95b3509SRandall Stewart printf("Unknown processor type 0x%lx Only Intel AMD64 types are supported by this routine!\n", ebx);
2357d95b3509SRandall Stewart exit(0);
2358d95b3509SRandall Stewart }
2359d95b3509SRandall Stewart cpuid(1, eax, ebx, ecx, edx);
2360d95b3509SRandall Stewart model = (((eax & 0xF0000) >> 12) | ((eax & 0xF0) >> 4));
2361d95b3509SRandall Stewart printf("CPU model is 0x%x id:0x%lx\n", model, eax);
2362d95b3509SRandall Stewart switch (eax & 0xF00) {
2363d95b3509SRandall Stewart case 0x500: /* Pentium family processors */
2364d95b3509SRandall Stewart printf("Intel Pentium P5\n");
2365d95b3509SRandall Stewart goto not_supported;
2366d95b3509SRandall Stewart break;
2367d95b3509SRandall Stewart case 0x600: /* Pentium Pro, Celeron, Pentium II & III */
2368d95b3509SRandall Stewart switch (model) {
2369d95b3509SRandall Stewart case 0x1:
2370d95b3509SRandall Stewart printf("Intel Pentium P6\n");
2371d95b3509SRandall Stewart goto not_supported;
2372d95b3509SRandall Stewart break;
2373d95b3509SRandall Stewart case 0x3:
2374d95b3509SRandall Stewart case 0x5:
2375d95b3509SRandall Stewart printf("Intel PII\n");
2376d95b3509SRandall Stewart goto not_supported;
2377d95b3509SRandall Stewart break;
2378eef0660aSRandall Stewart case 0x6: case 0x16:
2379d95b3509SRandall Stewart printf("Intel CL\n");
2380d95b3509SRandall Stewart goto not_supported;
2381d95b3509SRandall Stewart break;
2382eef0660aSRandall Stewart case 0x7: case 0x8: case 0xA: case 0xB:
2383d95b3509SRandall Stewart printf("Intel PIII\n");
2384d95b3509SRandall Stewart goto not_supported;
2385d95b3509SRandall Stewart break;
2386eef0660aSRandall Stewart case 0x9: case 0xD:
2387d95b3509SRandall Stewart printf("Intel PM\n");
2388d95b3509SRandall Stewart goto not_supported;
2389d95b3509SRandall Stewart break;
2390d95b3509SRandall Stewart case 0xE:
2391d95b3509SRandall Stewart printf("Intel CORE\n");
2392d95b3509SRandall Stewart goto not_supported;
2393d95b3509SRandall Stewart break;
2394d95b3509SRandall Stewart case 0xF:
2395d95b3509SRandall Stewart printf("Intel CORE2\n");
2396d95b3509SRandall Stewart goto not_supported;
2397d95b3509SRandall Stewart break;
2398d95b3509SRandall Stewart case 0x17:
2399d95b3509SRandall Stewart printf("Intel CORE2EXTREME\n");
2400d95b3509SRandall Stewart goto not_supported;
2401d95b3509SRandall Stewart break;
2402d95b3509SRandall Stewart case 0x1C: /* Per Intel document 320047-002. */
2403d95b3509SRandall Stewart printf("Intel ATOM\n");
2404d95b3509SRandall Stewart goto not_supported;
2405d95b3509SRandall Stewart break;
2406d95b3509SRandall Stewart case 0x1A:
2407eef0660aSRandall Stewart case 0x1E: /*
2408eef0660aSRandall Stewart * Per Intel document 253669-032 9/2009,
2409eef0660aSRandall Stewart * pages A-2 and A-57
2410eef0660aSRandall Stewart */
2411eef0660aSRandall Stewart case 0x1F: /*
2412eef0660aSRandall Stewart * Per Intel document 253669-032 9/2009,
2413eef0660aSRandall Stewart * pages A-2 and A-57
2414eef0660aSRandall Stewart */
2415d95b3509SRandall Stewart printf("Intel COREI7\n");
2416d95b3509SRandall Stewart goto not_supported;
2417d95b3509SRandall Stewart break;
2418d95b3509SRandall Stewart case 0x2E:
2419d95b3509SRandall Stewart printf("Intel NEHALEM\n");
2420d95b3509SRandall Stewart goto not_supported;
2421d95b3509SRandall Stewart break;
2422d95b3509SRandall Stewart case 0x25: /* Per Intel document 253669-033US 12/2009. */
2423d95b3509SRandall Stewart case 0x2C: /* Per Intel document 253669-033US 12/2009. */
2424d95b3509SRandall Stewart printf("Intel WESTMERE\n");
2425d95b3509SRandall Stewart goto not_supported;
2426d95b3509SRandall Stewart break;
2427d95b3509SRandall Stewart case 0x2F: /* Westmere-EX, seen in wild */
2428d95b3509SRandall Stewart printf("Intel WESTMERE\n");
2429d95b3509SRandall Stewart goto not_supported;
2430d95b3509SRandall Stewart break;
2431d95b3509SRandall Stewart case 0x2A: /* Per Intel document 253669-039US 05/2011. */
2432d95b3509SRandall Stewart printf("Intel SANDYBRIDGE\n");
2433d95b3509SRandall Stewart set_sandybridge();
2434d95b3509SRandall Stewart break;
2435d95b3509SRandall Stewart case 0x2D: /* Per Intel document 253669-044US 08/2012. */
2436d95b3509SRandall Stewart printf("Intel SANDYBRIDGE_XEON\n");
2437d95b3509SRandall Stewart set_sandybridge();
2438d95b3509SRandall Stewart break;
2439d95b3509SRandall Stewart case 0x3A: /* Per Intel document 253669-043US 05/2012. */
2440d95b3509SRandall Stewart printf("Intel IVYBRIDGE\n");
2441d95b3509SRandall Stewart set_ivybridge();
2442d95b3509SRandall Stewart break;
2443d95b3509SRandall Stewart case 0x3E: /* Per Intel document 325462-045US 01/2013. */
2444d95b3509SRandall Stewart printf("Intel IVYBRIDGE_XEON\n");
2445d95b3509SRandall Stewart set_ivybridge();
2446d95b3509SRandall Stewart break;
2447d95b3509SRandall Stewart case 0x3F: /* Per Intel document 325462-045US 09/2014. */
2448d95b3509SRandall Stewart printf("Intel HASWELL (Xeon)\n");
2449d95b3509SRandall Stewart set_haswell();
2450d95b3509SRandall Stewart break;
2451d95b3509SRandall Stewart case 0x3C: /* Per Intel document 325462-045US 01/2013. */
2452d95b3509SRandall Stewart case 0x45:
2453d95b3509SRandall Stewart case 0x46:
2454d95b3509SRandall Stewart printf("Intel HASWELL\n");
2455d95b3509SRandall Stewart set_haswell();
2456d95b3509SRandall Stewart break;
2457ade40db3SRandall Stewart
2458ade40db3SRandall Stewart case 0x4e:
2459ade40db3SRandall Stewart case 0x5e:
2460ade40db3SRandall Stewart printf("Intel SKY-LAKE\n");
2461ade40db3SRandall Stewart goto not_supported;
2462ade40db3SRandall Stewart break;
2463ade40db3SRandall Stewart case 0x3D:
2464ade40db3SRandall Stewart case 0x47:
2465ade40db3SRandall Stewart printf("Intel BROADWELL\n");
2466ade40db3SRandall Stewart set_broadwell();
2467ade40db3SRandall Stewart break;
2468ade40db3SRandall Stewart case 0x4f:
2469ade40db3SRandall Stewart case 0x56:
2470eef0660aSRandall Stewart printf("Intel BROADWEL (Xeon)\n");
2471ade40db3SRandall Stewart set_broadwell();
2472ade40db3SRandall Stewart break;
2473ade40db3SRandall Stewart
2474d95b3509SRandall Stewart case 0x4D:
2475d95b3509SRandall Stewart /* Per Intel document 330061-001 01/2014. */
2476d95b3509SRandall Stewart printf("Intel ATOM_SILVERMONT\n");
2477d95b3509SRandall Stewart goto not_supported;
2478d95b3509SRandall Stewart break;
2479d95b3509SRandall Stewart default:
2480d95b3509SRandall Stewart printf("Intel model 0x%x is not known -- sorry\n",
2481d95b3509SRandall Stewart model);
2482d95b3509SRandall Stewart goto not_supported;
2483d95b3509SRandall Stewart break;
2484d95b3509SRandall Stewart }
2485d95b3509SRandall Stewart break;
2486d95b3509SRandall Stewart case 0xF00: /* P4 */
2487d95b3509SRandall Stewart printf("Intel unknown model %d\n", model);
2488d95b3509SRandall Stewart goto not_supported;
2489d95b3509SRandall Stewart break;
2490d95b3509SRandall Stewart }
2491eef0660aSRandall Stewart do_cpuid(0xa, 0, reg);
2492eef0660aSRandall Stewart max_pmc_counters = (reg[3] & 0x0000000f) + 1;
2493eef0660aSRandall Stewart printf("We have %d PMC counters to work with\n", max_pmc_counters);
2494d95b3509SRandall Stewart /* Ok lets load the list of all known PMC's */
2495d95b3509SRandall Stewart io = my_popen("/usr/sbin/pmccontrol -L", "r", &pid_of_command);
2496d95b3509SRandall Stewart if (valid_pmcs == NULL) {
2497d95b3509SRandall Stewart /* Likely */
2498d95b3509SRandall Stewart pmc_allocated_cnt = PMC_INITIAL_ALLOC;
2499d95b3509SRandall Stewart sz = sizeof(char *) * pmc_allocated_cnt;
2500d95b3509SRandall Stewart valid_pmcs = malloc(sz);
2501d95b3509SRandall Stewart if (valid_pmcs == NULL) {
2502d95b3509SRandall Stewart printf("No memory allocation fails at startup?\n");
2503d95b3509SRandall Stewart exit(-1);
2504d95b3509SRandall Stewart }
2505d95b3509SRandall Stewart memset(valid_pmcs, 0, sz);
2506d95b3509SRandall Stewart }
2507eef0660aSRandall Stewart
2508d95b3509SRandall Stewart while (fgets(linebuf, sizeof(linebuf), io) != NULL) {
2509d95b3509SRandall Stewart if (linebuf[0] != '\t') {
2510d95b3509SRandall Stewart /* sometimes headers ;-) */
2511d95b3509SRandall Stewart continue;
2512d95b3509SRandall Stewart }
2513d95b3509SRandall Stewart len = strlen(linebuf);
2514d95b3509SRandall Stewart if (linebuf[(len-1)] == '\n') {
2515d95b3509SRandall Stewart /* Likely */
2516d95b3509SRandall Stewart linebuf[(len-1)] = 0;
2517d95b3509SRandall Stewart }
2518d95b3509SRandall Stewart str = &linebuf[1];
2519d95b3509SRandall Stewart len = strlen(str) + 1;
2520d95b3509SRandall Stewart valid_pmcs[valid_pmc_cnt] = malloc(len);
2521d95b3509SRandall Stewart if (valid_pmcs[valid_pmc_cnt] == NULL) {
2522d95b3509SRandall Stewart printf("No memory2 allocation fails at startup?\n");
2523d95b3509SRandall Stewart exit(-1);
2524d95b3509SRandall Stewart }
2525d95b3509SRandall Stewart memset(valid_pmcs[valid_pmc_cnt], 0, len);
2526d95b3509SRandall Stewart strcpy(valid_pmcs[valid_pmc_cnt], str);
2527d95b3509SRandall Stewart valid_pmc_cnt++;
2528d95b3509SRandall Stewart if (valid_pmc_cnt >= pmc_allocated_cnt) {
2529d95b3509SRandall Stewart /* Got to expand -- unlikely */
2530d95b3509SRandall Stewart char **more;
2531d95b3509SRandall Stewart
2532d95b3509SRandall Stewart sz = sizeof(char *) * (pmc_allocated_cnt * 2);
2533d95b3509SRandall Stewart more = malloc(sz);
2534d95b3509SRandall Stewart if (more == NULL) {
2535d95b3509SRandall Stewart printf("No memory3 allocation fails at startup?\n");
2536d95b3509SRandall Stewart exit(-1);
2537d95b3509SRandall Stewart }
25388a3bbeb2SRandall Stewart memset(more, 0, sz);
2539d95b3509SRandall Stewart memcpy(more, valid_pmcs, sz);
2540d95b3509SRandall Stewart pmc_allocated_cnt *= 2;
2541d95b3509SRandall Stewart free(valid_pmcs);
2542d95b3509SRandall Stewart valid_pmcs = more;
2543d95b3509SRandall Stewart }
2544d95b3509SRandall Stewart }
2545d95b3509SRandall Stewart my_pclose(io, pid_of_command);
2546d95b3509SRandall Stewart return;
2547d95b3509SRandall Stewart not_supported:
2548d95b3509SRandall Stewart printf("Not supported\n");
2549d95b3509SRandall Stewart exit(-1);
2550d95b3509SRandall Stewart }
2551d95b3509SRandall Stewart
2552d95b3509SRandall Stewart static void
explain_all(void)2553d95b3509SRandall Stewart explain_all(void)
2554d95b3509SRandall Stewart {
2555d95b3509SRandall Stewart int i;
2556d95b3509SRandall Stewart printf("For CPU's of type %s the following expressions are available:\n",the_cpu.cputype);
2557d95b3509SRandall Stewart printf("-------------------------------------------------------------\n");
2558d95b3509SRandall Stewart for(i=0; i<the_cpu.number; i++){
2559d95b3509SRandall Stewart printf("For -e %s ", the_cpu.ents[i].name);
2560d95b3509SRandall Stewart (*the_cpu.explain)(the_cpu.ents[i].name);
2561d95b3509SRandall Stewart printf("----------------------------\n");
2562d95b3509SRandall Stewart }
2563d95b3509SRandall Stewart }
2564d95b3509SRandall Stewart
2565d95b3509SRandall Stewart static void
test_for_a_pmc(const char * pmc,int out_so_far)2566d95b3509SRandall Stewart test_for_a_pmc(const char *pmc, int out_so_far)
2567d95b3509SRandall Stewart {
2568d95b3509SRandall Stewart FILE *io;
2569d95b3509SRandall Stewart pid_t pid_of_command=0;
2570d95b3509SRandall Stewart char my_command[1024];
2571d95b3509SRandall Stewart char line[1024];
2572d95b3509SRandall Stewart char resp[1024];
2573d95b3509SRandall Stewart int len, llen, i;
2574d95b3509SRandall Stewart
2575d95b3509SRandall Stewart if (out_so_far < 50) {
2576d95b3509SRandall Stewart len = 50 - out_so_far;
2577d95b3509SRandall Stewart for(i=0; i<len; i++) {
2578d95b3509SRandall Stewart printf(" ");
2579d95b3509SRandall Stewart }
2580d95b3509SRandall Stewart }
2581d95b3509SRandall Stewart sprintf(my_command, "/usr/sbin/pmcstat -w .25 -c 0 -s %s", pmc);
2582d95b3509SRandall Stewart io = my_popen(my_command, "r", &pid_of_command);
2583d95b3509SRandall Stewart if (io == NULL) {
2584d95b3509SRandall Stewart printf("Failed -- popen fails\n");
2585d95b3509SRandall Stewart return;
2586d95b3509SRandall Stewart }
2587d95b3509SRandall Stewart /* Setup what we expect */
2588d95b3509SRandall Stewart len = sprintf(resp, "%s", pmc);
2589d95b3509SRandall Stewart if (fgets(line, sizeof(line), io) == NULL) {
2590d95b3509SRandall Stewart printf("Failed -- no output from pmstat\n");
2591d95b3509SRandall Stewart goto out;
2592d95b3509SRandall Stewart }
2593d95b3509SRandall Stewart llen = strlen(line);
2594d95b3509SRandall Stewart if (line[(llen-1)] == '\n') {
2595d95b3509SRandall Stewart line[(llen-1)] = 0;
2596d95b3509SRandall Stewart llen--;
2597d95b3509SRandall Stewart }
2598d95b3509SRandall Stewart for(i=2; i<(llen-len); i++) {
2599d95b3509SRandall Stewart if (strncmp(&line[i], "ERROR", 5) == 0) {
2600d95b3509SRandall Stewart printf("Failed %s\n", line);
2601d95b3509SRandall Stewart goto out;
2602d95b3509SRandall Stewart } else if (strncmp(&line[i], resp, len) == 0) {
2603d95b3509SRandall Stewart int j, k;
2604d95b3509SRandall Stewart
2605d95b3509SRandall Stewart if (fgets(line, sizeof(line), io) == NULL) {
2606d95b3509SRandall Stewart printf("Failed -- no second output from pmstat\n");
2607d95b3509SRandall Stewart goto out;
2608d95b3509SRandall Stewart }
2609d95b3509SRandall Stewart len = strlen(line);
2610d95b3509SRandall Stewart for (j=0; j<len; j++) {
2611d95b3509SRandall Stewart if (line[j] == ' ') {
2612d95b3509SRandall Stewart j++;
2613d95b3509SRandall Stewart } else {
2614d95b3509SRandall Stewart break;
2615d95b3509SRandall Stewart }
2616d95b3509SRandall Stewart }
2617d95b3509SRandall Stewart printf("Pass");
2618d95b3509SRandall Stewart len = strlen(&line[j]);
2619d95b3509SRandall Stewart if (len < 20) {
2620d95b3509SRandall Stewart for(k=0; k<(20-len); k++) {
2621d95b3509SRandall Stewart printf(" ");
2622d95b3509SRandall Stewart }
2623d95b3509SRandall Stewart }
26244d9bf203SRandall Stewart if (len) {
2625d95b3509SRandall Stewart printf("%s", &line[j]);
26264d9bf203SRandall Stewart } else {
26274d9bf203SRandall Stewart printf("\n");
26284d9bf203SRandall Stewart }
2629d95b3509SRandall Stewart goto out;
2630d95b3509SRandall Stewart }
2631d95b3509SRandall Stewart }
2632d95b3509SRandall Stewart printf("Failed -- '%s' not '%s'\n", line, resp);
2633d95b3509SRandall Stewart out:
2634d95b3509SRandall Stewart my_pclose(io, pid_of_command);
2635d95b3509SRandall Stewart
2636d95b3509SRandall Stewart }
2637d95b3509SRandall Stewart
2638d95b3509SRandall Stewart static int
add_it_to(char ** vars,int cur_cnt,char * name)2639d95b3509SRandall Stewart add_it_to(char **vars, int cur_cnt, char *name)
2640d95b3509SRandall Stewart {
2641d95b3509SRandall Stewart int i;
2642d95b3509SRandall Stewart size_t len;
2643d95b3509SRandall Stewart for(i=0; i<cur_cnt; i++) {
2644d95b3509SRandall Stewart if (strcmp(vars[i], name) == 0) {
2645d95b3509SRandall Stewart /* Already have */
2646d95b3509SRandall Stewart return(0);
2647d95b3509SRandall Stewart }
2648d95b3509SRandall Stewart }
2649d95b3509SRandall Stewart if (vars[cur_cnt] != NULL) {
2650d95b3509SRandall Stewart printf("Cur_cnt:%d filled with %s??\n",
2651d95b3509SRandall Stewart cur_cnt, vars[cur_cnt]);
2652d95b3509SRandall Stewart exit(-1);
2653d95b3509SRandall Stewart }
2654d95b3509SRandall Stewart /* Ok its new */
2655d95b3509SRandall Stewart len = strlen(name) + 1;
2656d95b3509SRandall Stewart vars[cur_cnt] = malloc(len);
2657d95b3509SRandall Stewart if (vars[cur_cnt] == NULL) {
2658d95b3509SRandall Stewart printf("No memory %s\n", __FUNCTION__);
2659d95b3509SRandall Stewart exit(-1);
2660d95b3509SRandall Stewart }
2661d95b3509SRandall Stewart memset(vars[cur_cnt], 0, len);
2662d95b3509SRandall Stewart strcpy(vars[cur_cnt], name);
2663d95b3509SRandall Stewart return(1);
2664d95b3509SRandall Stewart }
2665d95b3509SRandall Stewart
2666d95b3509SRandall Stewart static char *
build_command_for_exp(struct expression * exp)2667d95b3509SRandall Stewart build_command_for_exp(struct expression *exp)
2668d95b3509SRandall Stewart {
2669d95b3509SRandall Stewart /*
2670eef0660aSRandall Stewart * Build the pmcstat command to handle
2671eef0660aSRandall Stewart * the passed in expression.
2672eef0660aSRandall Stewart * /usr/sbin/pmcstat -w 1 -s NNN -s QQQ
2673eef0660aSRandall Stewart * where NNN and QQQ represent the PMC's in the expression
2674eef0660aSRandall Stewart * uniquely..
2675d95b3509SRandall Stewart */
2676d95b3509SRandall Stewart char forming[1024];
2677d95b3509SRandall Stewart int cnt_pmc, alloced_pmcs, i;
2678d95b3509SRandall Stewart struct expression *at;
2679d95b3509SRandall Stewart char **vars, *cmd;
2680d95b3509SRandall Stewart size_t mal;
2681d95b3509SRandall Stewart
2682d95b3509SRandall Stewart alloced_pmcs = cnt_pmc = 0;
2683d95b3509SRandall Stewart /* first how many do we have */
2684d95b3509SRandall Stewart at = exp;
2685d95b3509SRandall Stewart while (at) {
2686d95b3509SRandall Stewart if (at->type == TYPE_VALUE_PMC) {
2687d95b3509SRandall Stewart cnt_pmc++;
2688d95b3509SRandall Stewart }
2689d95b3509SRandall Stewart at = at->next;
2690d95b3509SRandall Stewart }
2691d95b3509SRandall Stewart if (cnt_pmc == 0) {
2692d95b3509SRandall Stewart printf("No PMC's in your expression -- nothing to do!!\n");
2693d95b3509SRandall Stewart exit(0);
2694d95b3509SRandall Stewart }
2695d95b3509SRandall Stewart mal = cnt_pmc * sizeof(char *);
2696d95b3509SRandall Stewart vars = malloc(mal);
2697d95b3509SRandall Stewart if (vars == NULL) {
2698d95b3509SRandall Stewart printf("No memory\n");
2699d95b3509SRandall Stewart exit(-1);
2700d95b3509SRandall Stewart }
2701d95b3509SRandall Stewart memset(vars, 0, mal);
2702d95b3509SRandall Stewart at = exp;
2703d95b3509SRandall Stewart while (at) {
2704d95b3509SRandall Stewart if (at->type == TYPE_VALUE_PMC) {
2705d95b3509SRandall Stewart if(add_it_to(vars, alloced_pmcs, at->name)) {
2706d95b3509SRandall Stewart alloced_pmcs++;
2707d95b3509SRandall Stewart }
2708d95b3509SRandall Stewart }
2709d95b3509SRandall Stewart at = at->next;
2710d95b3509SRandall Stewart }
2711d95b3509SRandall Stewart /* Now we have a unique list in vars so create our command */
2712d95b3509SRandall Stewart mal = 23; /* "/usr/sbin/pmcstat -w 1" + \0 */
2713d95b3509SRandall Stewart for(i=0; i<alloced_pmcs; i++) {
2714d95b3509SRandall Stewart mal += strlen(vars[i]) + 4; /* var + " -s " */
2715d95b3509SRandall Stewart }
2716d95b3509SRandall Stewart cmd = malloc((mal+2));
2717d95b3509SRandall Stewart if (cmd == NULL) {
2718d95b3509SRandall Stewart printf("%s out of mem\n", __FUNCTION__);
2719d95b3509SRandall Stewart exit(-1);
2720d95b3509SRandall Stewart }
2721d95b3509SRandall Stewart memset(cmd, 0, (mal+2));
2722d95b3509SRandall Stewart strcpy(cmd, "/usr/sbin/pmcstat -w 1");
2723d95b3509SRandall Stewart at = exp;
2724d95b3509SRandall Stewart for(i=0; i<alloced_pmcs; i++) {
2725d95b3509SRandall Stewart sprintf(forming, " -s %s", vars[i]);
2726d95b3509SRandall Stewart strcat(cmd, forming);
2727d95b3509SRandall Stewart free(vars[i]);
2728d95b3509SRandall Stewart vars[i] = NULL;
2729d95b3509SRandall Stewart }
2730d95b3509SRandall Stewart free(vars);
2731d95b3509SRandall Stewart return(cmd);
2732d95b3509SRandall Stewart }
2733d95b3509SRandall Stewart
2734d95b3509SRandall Stewart static int
user_expr(struct counters * cpu,int pos)2735d95b3509SRandall Stewart user_expr(struct counters *cpu, int pos)
2736d95b3509SRandall Stewart {
2737d95b3509SRandall Stewart int ret;
2738d95b3509SRandall Stewart double res;
2739d95b3509SRandall Stewart struct counters *var;
2740d95b3509SRandall Stewart struct expression *at;
2741d95b3509SRandall Stewart
2742d95b3509SRandall Stewart at = master_exp;
2743d95b3509SRandall Stewart while (at) {
2744d95b3509SRandall Stewart if (at->type == TYPE_VALUE_PMC) {
2745d95b3509SRandall Stewart var = find_counter(cpu, at->name);
2746d95b3509SRandall Stewart if (var == NULL) {
2747d95b3509SRandall Stewart printf("%s:Can't find counter %s?\n", __FUNCTION__, at->name);
2748d95b3509SRandall Stewart exit(-1);
2749d95b3509SRandall Stewart }
2750d95b3509SRandall Stewart if (pos != -1) {
2751d95b3509SRandall Stewart at->value = var->vals[pos] * 1.0;
2752d95b3509SRandall Stewart } else {
2753d95b3509SRandall Stewart at->value = var->sum * 1.0;
2754d95b3509SRandall Stewart }
2755d95b3509SRandall Stewart }
2756d95b3509SRandall Stewart at = at->next;
2757d95b3509SRandall Stewart }
2758d95b3509SRandall Stewart res = run_expr(master_exp, 1, NULL);
2759d95b3509SRandall Stewart ret = printf("%1.3f", res);
2760d95b3509SRandall Stewart return(ret);
2761d95b3509SRandall Stewart }
2762d95b3509SRandall Stewart
2763d95b3509SRandall Stewart
2764d95b3509SRandall Stewart static void
set_manual_exp(struct expression * exp)2765d95b3509SRandall Stewart set_manual_exp(struct expression *exp)
2766d95b3509SRandall Stewart {
2767d95b3509SRandall Stewart expression = user_expr;
2768d95b3509SRandall Stewart command = build_command_for_exp(exp);
2769d95b3509SRandall Stewart threshold = "User defined threshold";
2770d95b3509SRandall Stewart }
2771d95b3509SRandall Stewart
2772d95b3509SRandall Stewart static void
run_tests(void)2773d95b3509SRandall Stewart run_tests(void)
2774d95b3509SRandall Stewart {
2775d95b3509SRandall Stewart int i, lenout;
2776d95b3509SRandall Stewart printf("Running tests on %d PMC's this may take some time\n", valid_pmc_cnt);
2777d95b3509SRandall Stewart printf("------------------------------------------------------------------------\n");
2778d95b3509SRandall Stewart for(i=0; i<valid_pmc_cnt; i++) {
2779d95b3509SRandall Stewart lenout = printf("%s", valid_pmcs[i]);
2780d95b3509SRandall Stewart fflush(stdout);
2781d95b3509SRandall Stewart test_for_a_pmc(valid_pmcs[i], lenout);
2782d95b3509SRandall Stewart }
2783d95b3509SRandall Stewart }
2784d95b3509SRandall Stewart static void
list_all(void)2785d95b3509SRandall Stewart list_all(void)
2786d95b3509SRandall Stewart {
2787d95b3509SRandall Stewart int i, cnt, j;
2788d95b3509SRandall Stewart printf("PMC Abbreviation\n");
2789d95b3509SRandall Stewart printf("--------------------------------------------------------------\n");
2790d95b3509SRandall Stewart for(i=0; i<valid_pmc_cnt; i++) {
2791d95b3509SRandall Stewart cnt = printf("%s", valid_pmcs[i]);
2792d95b3509SRandall Stewart for(j=cnt; j<52; j++) {
2793d95b3509SRandall Stewart printf(" ");
2794d95b3509SRandall Stewart }
2795d95b3509SRandall Stewart printf("%%%d\n", i);
2796d95b3509SRandall Stewart }
2797d95b3509SRandall Stewart }
2798d95b3509SRandall Stewart
2799d95b3509SRandall Stewart
2800d95b3509SRandall Stewart int
main(int argc,char ** argv)2801d95b3509SRandall Stewart main(int argc, char **argv)
2802d95b3509SRandall Stewart {
2803d95b3509SRandall Stewart int i, j, cnt;
2804d95b3509SRandall Stewart char *filename=NULL;
2805eef0660aSRandall Stewart const char *name=NULL;
2806d95b3509SRandall Stewart int help_only = 0;
2807d95b3509SRandall Stewart int test_mode = 0;
2808eef0660aSRandall Stewart int test_at = 0;
2809d95b3509SRandall Stewart
2810d95b3509SRandall Stewart get_cpuid_set();
2811d95b3509SRandall Stewart memset(glob_cpu, 0, sizeof(glob_cpu));
2812eef0660aSRandall Stewart while ((i = getopt(argc, argv, "ALHhvm:i:?e:TE:")) != -1) {
2813d95b3509SRandall Stewart switch (i) {
2814eef0660aSRandall Stewart case 'A':
2815eef0660aSRandall Stewart run_all = 1;
2816eef0660aSRandall Stewart break;
2817d95b3509SRandall Stewart case 'L':
2818d95b3509SRandall Stewart list_all();
2819d95b3509SRandall Stewart return(0);
2820d95b3509SRandall Stewart case 'H':
2821d95b3509SRandall Stewart printf("**********************************\n");
2822d95b3509SRandall Stewart explain_all();
2823d95b3509SRandall Stewart printf("**********************************\n");
2824d95b3509SRandall Stewart return(0);
2825d95b3509SRandall Stewart break;
2826d95b3509SRandall Stewart case 'T':
2827d95b3509SRandall Stewart test_mode = 1;
2828d95b3509SRandall Stewart break;
2829d95b3509SRandall Stewart case 'E':
2830d95b3509SRandall Stewart master_exp = parse_expression(optarg);
2831d95b3509SRandall Stewart if (master_exp) {
2832d95b3509SRandall Stewart set_manual_exp(master_exp);
2833d95b3509SRandall Stewart }
2834d95b3509SRandall Stewart break;
2835d95b3509SRandall Stewart case 'e':
2836d95b3509SRandall Stewart if (validate_expression(optarg)) {
2837d95b3509SRandall Stewart printf("Unknown expression %s\n", optarg);
2838d95b3509SRandall Stewart return(0);
2839d95b3509SRandall Stewart }
2840d95b3509SRandall Stewart name = optarg;
2841d95b3509SRandall Stewart set_expression(optarg);
2842d95b3509SRandall Stewart break;
2843d95b3509SRandall Stewart case 'm':
2844d95b3509SRandall Stewart max_to_collect = strtol(optarg, NULL, 0);
2845d95b3509SRandall Stewart if (max_to_collect > MAX_COUNTER_SLOTS) {
2846d95b3509SRandall Stewart /* You can't collect more than max in array */
2847d95b3509SRandall Stewart max_to_collect = MAX_COUNTER_SLOTS;
2848d95b3509SRandall Stewart }
2849d95b3509SRandall Stewart break;
2850d95b3509SRandall Stewart case 'v':
2851d95b3509SRandall Stewart verbose++;
2852d95b3509SRandall Stewart break;
2853d95b3509SRandall Stewart case 'h':
2854d95b3509SRandall Stewart help_only = 1;
2855d95b3509SRandall Stewart break;
2856d95b3509SRandall Stewart case 'i':
2857d95b3509SRandall Stewart filename = optarg;
2858d95b3509SRandall Stewart break;
2859d95b3509SRandall Stewart case '?':
2860d95b3509SRandall Stewart default:
2861d95b3509SRandall Stewart use:
2862d95b3509SRandall Stewart printf("Use %s [ -i inputfile -v -m max_to_collect -e expr -E -h -? -H]\n",
2863d95b3509SRandall Stewart argv[0]);
2864d95b3509SRandall Stewart printf("-i inputfile -- use source as inputfile not stdin (if stdin collect)\n");
2865d95b3509SRandall Stewart printf("-v -- verbose dump debug type things -- you don't want this\n");
2866*340e08beSGordon Bergling printf("-m N -- maximum to collect is N measurements\n");
2867d95b3509SRandall Stewart printf("-e expr-name -- Do expression expr-name\n");
2868d95b3509SRandall Stewart printf("-E 'your expression' -- Do your expression\n");
2869d95b3509SRandall Stewart printf("-h -- Don't do the expression I put in -e xxx just explain what it does and exit\n");
2870d95b3509SRandall Stewart printf("-H -- Don't run anything, just explain all canned expressions\n");
2871d95b3509SRandall Stewart printf("-T -- Test all PMC's defined by this processor\n");
2872eef0660aSRandall Stewart printf("-A -- Run all canned tests\n");
2873d95b3509SRandall Stewart return(0);
2874d95b3509SRandall Stewart break;
287580c7cc1cSPedro F. Giffuni }
2876d95b3509SRandall Stewart }
2877eef0660aSRandall Stewart if ((run_all == 0) && (name == NULL) && (filename == NULL) &&
2878eef0660aSRandall Stewart (test_mode == 0) && (master_exp == NULL)) {
2879d95b3509SRandall Stewart printf("Without setting an expression we cannot dynamically gather information\n");
2880d95b3509SRandall Stewart printf("you must supply a filename (and you probably want verbosity)\n");
2881d95b3509SRandall Stewart goto use;
2882d95b3509SRandall Stewart }
2883eef0660aSRandall Stewart if (run_all && max_to_collect > 10) {
2884eef0660aSRandall Stewart max_to_collect = 3;
2885eef0660aSRandall Stewart }
2886d95b3509SRandall Stewart if (test_mode) {
2887d95b3509SRandall Stewart run_tests();
2888d95b3509SRandall Stewart return(0);
2889d95b3509SRandall Stewart }
2890d95b3509SRandall Stewart printf("*********************************\n");
2891eef0660aSRandall Stewart if ((master_exp == NULL) && name) {
2892d95b3509SRandall Stewart (*the_cpu.explain)(name);
2893eef0660aSRandall Stewart } else if (master_exp) {
2894d95b3509SRandall Stewart printf("Examine your expression ");
2895d95b3509SRandall Stewart print_exp(master_exp);
2896d95b3509SRandall Stewart printf("User defined threshold\n");
2897d95b3509SRandall Stewart }
2898d95b3509SRandall Stewart if (help_only) {
2899d95b3509SRandall Stewart return(0);
2900d95b3509SRandall Stewart }
2901eef0660aSRandall Stewart if (run_all) {
2902eef0660aSRandall Stewart more:
2903eef0660aSRandall Stewart name = the_cpu.ents[test_at].name;
2904eef0660aSRandall Stewart printf("***Test %s (threshold %s)****\n", name, the_cpu.ents[test_at].thresh);
2905eef0660aSRandall Stewart test_at++;
2906eef0660aSRandall Stewart if (set_expression(name) == -1) {
2907eef0660aSRandall Stewart if (test_at >= the_cpu.number) {
2908eef0660aSRandall Stewart goto done;
2909eef0660aSRandall Stewart } else
2910eef0660aSRandall Stewart goto more;
2911eef0660aSRandall Stewart }
2912eef0660aSRandall Stewart
2913eef0660aSRandall Stewart }
2914d95b3509SRandall Stewart process_file(filename);
2915d95b3509SRandall Stewart if (verbose >= 2) {
2916d95b3509SRandall Stewart for (i=0; i<ncnts; i++) {
2917d95b3509SRandall Stewart printf("Counter:%s cpu:%d index:%d\n",
2918d95b3509SRandall Stewart cnts[i].counter_name,
2919d95b3509SRandall Stewart cnts[i].cpu, i);
2920d95b3509SRandall Stewart for(j=0; j<cnts[i].pos; j++) {
2921d95b3509SRandall Stewart printf(" val - %ld\n", (long int)cnts[i].vals[j]);
2922d95b3509SRandall Stewart }
2923d95b3509SRandall Stewart printf(" sum - %ld\n", (long int)cnts[i].sum);
2924d95b3509SRandall Stewart }
2925d95b3509SRandall Stewart }
2926d95b3509SRandall Stewart if (expression == NULL) {
2927d95b3509SRandall Stewart return(0);
2928d95b3509SRandall Stewart }
2929eef0660aSRandall Stewart if (max_to_collect > 1) {
2930d95b3509SRandall Stewart for(i=0, cnt=0; i<MAX_CPU; i++) {
2931d95b3509SRandall Stewart if (glob_cpu[i]) {
2932d95b3509SRandall Stewart do_expression(glob_cpu[i], -1);
2933d95b3509SRandall Stewart cnt++;
2934d95b3509SRandall Stewart if (cnt == cpu_count_out) {
2935d95b3509SRandall Stewart printf("\n");
2936d95b3509SRandall Stewart break;
2937d95b3509SRandall Stewart } else {
2938d95b3509SRandall Stewart printf("\t");
2939d95b3509SRandall Stewart }
2940d95b3509SRandall Stewart }
2941d95b3509SRandall Stewart }
2942eef0660aSRandall Stewart }
2943eef0660aSRandall Stewart if (run_all && (test_at < the_cpu.number)) {
2944eef0660aSRandall Stewart memset(glob_cpu, 0, sizeof(glob_cpu));
2945eef0660aSRandall Stewart ncnts = 0;
2946eef0660aSRandall Stewart printf("*********************************\n");
2947eef0660aSRandall Stewart goto more;
2948eef0660aSRandall Stewart } else if (run_all) {
2949eef0660aSRandall Stewart done:
2950eef0660aSRandall Stewart printf("*********************************\n");
2951eef0660aSRandall Stewart }
2952d95b3509SRandall Stewart return(0);
2953d95b3509SRandall Stewart }
2954