* Test program for counters in groups
@ 2009-03-17 23:27 Paul Mackerras
2009-03-17 23:55 ` Peter Zijlstra
2009-03-19 17:41 ` Peter Zijlstra
0 siblings, 2 replies; 3+ messages in thread
From: Paul Mackerras @ 2009-03-17 23:27 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Thomas Gleixner; +Cc: linux-kernel
[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 1688 bytes --]
Here's a little test program that checks whether software counters
(specifically, the task clock counter) work correctly when they're in
a group with hardware counters.
What it does is to create several groups, each with one hardware
counter, counting instructions, plus a task clock counter. It needs
to know an upper bound N on the number of hardware counters you have
(N defaults to 8), and it creates N+4 groups to force them to be
multiplexed. It also creates an overall task clock counter.
Then it spins for a while, and then stops all the counters and reads
them. It takes the total of the task clock counters in the groups and
computes the ratio of that total to the overall execution time from
the overall task clock counter.
That ratio should be equal to the number of actual hardware counters
that can count instructions. If the task clock counters in the groups
don't stop when their group gets taken off the PMU, the ratio will
instead be close to N+4. The program will declare that the test fails
if the ratio is greater than N (actually, N + 0.0001 to allow for FP
rounding errors).
Could someone run this on x86 on the latest PCL tree and let me know
what happens? I don't have an x86 crash box easily to hand. On
powerpc, it passes, but I think that is because I am missing setting
counter->prev_count in arch/powerpc/kernel/perf_counter.c, and I think
that means that enabling/disabling a group with a task clock counter
in it won't work correctly (I'll do a test program for that next).
Usage is: swsched-test [-c num-hw-counters] [-v]
Use -c N if you have more than 8 hardware counters. The -v flag makes
it print out the values of each counter.
Paul.
[-- Attachment #2: counter group test program --]
[-- Type: text/x-csrc, Size: 3119 bytes --]
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include "perf_counter.h"
#ifdef __x86_64__
# define __NR_perf_counter_open 295
#endif
#ifdef __i386__
# define __NR_perf_counter_open 333
#endif
#ifdef __powerpc__
# define __NR_perf_counter_open 319
#endif
#define PR_TASK_PERF_COUNTERS_DISABLE 31
#define PR_TASK_PERF_COUNTERS_ENABLE 32
int sys_perf_counter_open(struct perf_counter_hw_event *hw_event,
pid_t pid, int cpu, int group_fd, unsigned long flags)
{
return syscall(__NR_perf_counter_open, hw_event, pid, cpu, group_fd,
flags);
}
#define MAX_CTRS 50
#define LOOPS 1000000000
void do_work(void)
{
int i;
for (i = 0; i < LOOPS; ++i)
asm volatile("" : : "g" (i));
}
main(int ac, char **av)
{
int tsk0;
int hwfd[MAX_CTRS], tskfd[MAX_CTRS];
struct perf_counter_hw_event tsk_event;
struct perf_counter_hw_event hw_event;
unsigned long long vt0, vt[MAX_CTRS], vh[MAX_CTRS], vtsum, vhsum;
int i, n, nhw;
int verbose = 0;
double ratio;
nhw = 8;
while ((i = getopt(ac, av, "c:v")) != -1) {
switch (i) {
case 'c':
n = atoi(optarg);
break;
case 'v':
verbose = 1;
break;
case '?':
fprintf(stderr, "Usage: %s [-c #hwctrs] [-v]\n", av[0]);
exit(1);
}
}
if (nhw < 0 || nhw > MAX_CTRS - 4) {
fprintf(stderr, "invalid number of hw counters specified: %d\n",
nhw);
exit(1);
}
n = nhw + 4;
memset(&tsk_event, 0, sizeof(tsk_event));
tsk_event.type = PERF_COUNT_TASK_CLOCK;
tsk_event.disabled = 1;
memset(&hw_event, 0, sizeof(hw_event));
hw_event.disabled = 1;
hw_event.type = PERF_COUNT_INSTRUCTIONS;
tsk0 = sys_perf_counter_open(&tsk_event, 0, -1, -1, 0);
if (tsk0 == -1) {
perror("perf_counter_open");
exit(1);
}
tsk_event.disabled = 0;
for (i = 0; i < n; ++i) {
hwfd[i] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0);
tskfd[i] = sys_perf_counter_open(&tsk_event, 0, -1, hwfd[i], 0);
if (tskfd[i] == -1 || hwfd[i] == -1) {
perror("perf_counter_open");
exit(1);
}
}
prctl(PR_TASK_PERF_COUNTERS_ENABLE);
do_work();
prctl(PR_TASK_PERF_COUNTERS_DISABLE);
if (read(tsk0, &vt0, sizeof(vt0)) != sizeof(vt0)) {
fprintf(stderr, "error reading task clock counter\n");
exit(1);
}
vtsum = vhsum = 0;
for (i = 0; i < n; ++i) {
if (read(tskfd[i], &vt[i], sizeof(vt[i])) != sizeof(vt[i]) ||
read(hwfd[i], &vh[i], sizeof(vh[i])) != sizeof(vh[i])) {
fprintf(stderr, "error reading counter(s)\n");
exit(1);
}
vtsum += vt[i];
vhsum += vh[i];
}
printf("overall task clock: %lld\n", vt0);
printf("hw sum: %lld, task clock sum: %lld\n", vhsum, vtsum);
if (verbose) {
printf("hw counters:");
for (i = 0; i < n; ++i)
printf(" %lld", vh[i]);
printf("\ntask clock counters:");
for (i = 0; i < n; ++i)
printf(" %lld", vt[i]);
printf("\n");
}
ratio = (double)vtsum / vt0;
printf("ratio: %.2f\n", ratio);
if (ratio > nhw + 0.0001) {
fprintf(stderr, "test failed\n");
exit(1);
}
fprintf(stderr, "test passed\n");
exit(0);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Test program for counters in groups
2009-03-17 23:27 Test program for counters in groups Paul Mackerras
@ 2009-03-17 23:55 ` Peter Zijlstra
2009-03-19 17:41 ` Peter Zijlstra
1 sibling, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2009-03-17 23:55 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Ingo Molnar, Thomas Gleixner, linux-kernel
On Wed, 2009-03-18 at 10:27 +1100, Paul Mackerras wrote:
> Here's a little test program that checks whether software counters
> (specifically, the task clock counter) work correctly when they're in
> a group with hardware counters.
>
> What it does is to create several groups, each with one hardware
> counter, counting instructions, plus a task clock counter. It needs
> to know an upper bound N on the number of hardware counters you have
> (N defaults to 8), and it creates N+4 groups to force them to be
> multiplexed. It also creates an overall task clock counter.
>
> Then it spins for a while, and then stops all the counters and reads
> them. It takes the total of the task clock counters in the groups and
> computes the ratio of that total to the overall execution time from
> the overall task clock counter.
>
> That ratio should be equal to the number of actual hardware counters
> that can count instructions. If the task clock counters in the groups
> don't stop when their group gets taken off the PMU, the ratio will
> instead be close to N+4. The program will declare that the test fails
> if the ratio is greater than N (actually, N + 0.0001 to allow for FP
> rounding errors).
>
> Could someone run this on x86 on the latest PCL tree and let me know
> what happens? I don't have an x86 crash box easily to hand. On
> powerpc, it passes, but I think that is because I am missing setting
> counter->prev_count in arch/powerpc/kernel/perf_counter.c, and I think
> that means that enabling/disabling a group with a task clock counter
> in it won't work correctly (I'll do a test program for that next).
>
> Usage is: swsched-test [-c num-hw-counters] [-v]
>
> Use -c N if you have more than 8 hardware counters. The -v flag makes
> it print out the values of each counter.
I'll give it a run when I'm awake again, with the patches I send out --
esp the last one, x86 might stand a chance of actually working.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Test program for counters in groups
2009-03-17 23:27 Test program for counters in groups Paul Mackerras
2009-03-17 23:55 ` Peter Zijlstra
@ 2009-03-19 17:41 ` Peter Zijlstra
1 sibling, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2009-03-19 17:41 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Ingo Molnar, Thomas Gleixner, linux-kernel
On Wed, 2009-03-18 at 10:27 +1100, Paul Mackerras wrote:
> Here's a little test program that checks whether software counters
> (specifically, the task clock counter) work correctly when they're in
> a group with hardware counters.
>
> What it does is to create several groups, each with one hardware
> counter, counting instructions, plus a task clock counter. It needs
> to know an upper bound N on the number of hardware counters you have
> (N defaults to 8), and it creates N+4 groups to force them to be
> multiplexed. It also creates an overall task clock counter.
>
> Then it spins for a while, and then stops all the counters and reads
> them. It takes the total of the task clock counters in the groups and
> computes the ratio of that total to the overall execution time from
> the overall task clock counter.
>
> That ratio should be equal to the number of actual hardware counters
> that can count instructions. If the task clock counters in the groups
> don't stop when their group gets taken off the PMU, the ratio will
> instead be close to N+4. The program will declare that the test fails
> if the ratio is greater than N (actually, N + 0.0001 to allow for FP
> rounding errors).
>
> Could someone run this on x86 on the latest PCL tree and let me know
> what happens? I don't have an x86 crash box easily to hand. On
> powerpc, it passes, but I think that is because I am missing setting
> counter->prev_count in arch/powerpc/kernel/perf_counter.c, and I think
> that means that enabling/disabling a group with a task clock counter
> in it won't work correctly (I'll do a test program for that next).
>
> Usage is: swsched-test [-c num-hw-counters] [-v]
>
> Use -c N if you have more than 8 hardware counters. The -v flag makes
> it print out the values of each counter.
Adapted the thing a little for the latest ABI, but it seems to work:
[root@opteron ~]# ./swsched-test
overall task clock: 3211403572
hw sum: 12150279972, task clock sum: 12845614288
ratio: 4.00
test passed
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-03-19 17:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-17 23:27 Test program for counters in groups Paul Mackerras
2009-03-17 23:55 ` Peter Zijlstra
2009-03-19 17:41 ` Peter Zijlstra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox