* perf_counters issue remapped count
@ 2009-08-11 22:04 stephane eranian
2009-08-13 9:56 ` Ingo Molnar
0 siblings, 1 reply; 3+ messages in thread
From: stephane eranian @ 2009-08-11 22:04 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Ingo Molnar, LKML, Andrew Morton, Thomas Gleixner,
Robert Richter, Paul Mackerras, Andi Kleen, Maynard Johnson,
Carl Love, Corey J Ashford, Philip Mucci, Dan Terpstra,
perfmon2-devel
Hi,
I am trying to use the remapped counter feature
on Intel Core. It does not work as expected.
Well, in fact, it segfaults immediately, but that's because
you have not enabled PCE in cr4. But assume you have
for a moment. Them there are still several problems.
1/ hdr->index does not work with fixed counters
On Intel, RDPMC supports fixed counters, however, you
have to add an offset 0x40000000 to the index (see Intel
Vol 2b RDPMC description).
From what I can see in:
static int perf_counter_index(struct perf_counter *counter)
{
if (counter->state != PERF_COUNTER_STATE_ACTIVE)
return 0;
return counter->hw.idx + 1 - PERF_COUNTER_INDEX_OFFSET;
}
It cannot be made to work for both generic and fixed counters.
I think this function has to go in arch-specific code or become
more complicated.
2/ rdpmc() + offset returns bogus counts
Suppose you are using a generic counter, RDPMC returns the live
40-bit value of the counter. Then, my understanding is that you are
supposed to addr hdr->offset to that value to reconstruct the full
64-bit value.
It appears this is not quite working. Here is small example counting
PERF_COUNT_HW_BRANCH_INSTRUCTIONS.
RDPMC RAW hdr->offset
34a1 offset=0x0
3bac offset=0x0
40e4 offset=0x0
461c offset=0x0
4b54 offset=0x0
508c offset=0x0
55c4 offset=0x0
5afc offset=0x0
6034 offset=0x0
656c offset=0x0
6aa4 offset=0x0
6fdc offset=0x0
7514 offset=0x0
7a4c offset=0x0
7f84 offset=0x0
84bc offset=0x0
89f4 offset=0x0
8f2c offset=0x0
9464 offset=0x0
999c offset=0x0
9ed4 offset=0x0
ac20 offset=0x0
ff8000bbe9 offset=0x7fffffff
ff8000bf15 offset=0x7fffffff
ff8000c241 offset=0x7fffffff
ff8000c56d offset=0x7fffffff
ff8000c899 offset=0x7fffffff
ff8000cbc5 offset=0x7fffffff
ff8000cef1 offset=0x7fffffff
ff8000d21d offset=0x7fffffff
ff8000d549 offset=0x7fffffff
It appears at some point, the live value of the counter is changed and suddenly
you set bit 31 (bit32-39 are sign extension). Don't think it is because of PMU
interrupt, I suspect something wrong during context switching.
The core of my loop is as follows:
for(;;) {
for (i=0; i < num; i++) {
uint64_t offset = 0;
uint64_t values[3];
do {
seq = hdr->lock;
barrier();
if (hdr->index > 0) {
values[0] = rdpmc(hdr->index-1);
offset = hdr->offset;
//values[0] += offset;
values[1] = hdr->time_enabled;
values[2] = hdr->time_running;
} else {
ret = read(fd, values, sizeof(values));
break;
}
barrier();
} while (hdr->lock != seq);
if (values[2])
values[0]=
(uint64_t)((double)values[0] * values[1]/values[2]);
printf("%20"PRIx64" offset=0x%"PRIx64"\n",
values[0],
offset);
}
fib(10);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: perf_counters issue remapped count
2009-08-11 22:04 perf_counters issue remapped count stephane eranian
@ 2009-08-13 9:56 ` Ingo Molnar
2009-08-13 11:14 ` stephane eranian
0 siblings, 1 reply; 3+ messages in thread
From: Ingo Molnar @ 2009-08-13 9:56 UTC (permalink / raw)
To: eranian
Cc: Peter Zijlstra, LKML, Andrew Morton, Thomas Gleixner,
Robert Richter, Paul Mackerras, Andi Kleen, Maynard Johnson,
Carl Love, Corey J Ashford, Philip Mucci, Dan Terpstra,
perfmon2-devel
* stephane eranian <eranian@googlemail.com> wrote:
> Hi,
>
> I am trying to use the remapped counter feature
> on Intel Core. It does not work as expected.
it would be highly useful if you posted the .c files you used to
test it.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: perf_counters issue remapped count
2009-08-13 9:56 ` Ingo Molnar
@ 2009-08-13 11:14 ` stephane eranian
0 siblings, 0 replies; 3+ messages in thread
From: stephane eranian @ 2009-08-13 11:14 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, LKML, Andrew Morton, Thomas Gleixner,
Robert Richter, Paul Mackerras, Andi Kleen, Maynard Johnson,
Carl Love, Corey J Ashford, Philip Mucci, Dan Terpstra,
perfmon2-devel
On Thu, Aug 13, 2009 at 11:56 AM, Ingo Molnar<mingo@elte.hu> wrote:
>
> * stephane eranian <eranian@googlemail.com> wrote:
>
>> Hi,
>>
>> I am trying to use the remapped counter feature
>> on Intel Core. It does not work as expected.
>
> it would be highly useful if you posted the .c files you used to
> test it.
>
Here it is. It assumes you have enabled PCE in CR4 on all your CPUs.
I used BRANCH to ensure it would not use a fixed counter given the
hdr->index is wrong for those.
#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <err.h>
#include <perf_counter.h>
#ifdef __x86_64__
#define DECLARE_ARGS(val, low, high) unsigned low, high
#define EAX_EDX_VAL(val, low, high) ((low) | ((uint64_t )(high) << 32))
#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high)
#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
#else
#define DECLARE_ARGS(val, low, high) unsigned long long val
#define EAX_EDX_VAL(val, low, high) (val)
#define EAX_EDX_ARGS(val, low, high) "A" (val)
#define EAX_EDX_RET(val, low, high) "=A" (val)
#endif
#define barrier() __asm__ __volatile__("": : :"memory")
static inline unsigned long long rdpmc(int counter)
{
unsigned low, high;
asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
return EAX_EDX_VAL(val, low, high);
}
static volatile int quit;
void sig_handler(int n)
{
quit = 1;
}
/*
* our test code (function cannot be made static otherwise it is optimized away)
*/
unsigned long
fib(unsigned long n)
{
if (n == 0)
return 0;
if (n == 1)
return 2;
return fib(n-1)+fib(n-2);
}
int
main(int argc, char **argv)
{
struct perf_counter_mmap_page *hdr;
struct perf_counter_attr hw;
char *name;
uint64_t values[3];
int ret, fd, src;
unsigned int seq;
memset(&hw, 0, sizeof(hw));
/* make sure we do not use a fixed counter event */
name = "PERF_COUNT_HW_BRANCH_INSTRUCTIONS";
hw.type = PERF_TYPE_HARDWARE;
hw.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
hw.read_format =
PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING;
hw.disabled = 0;
fd = perf_counter_open(&hw, 0, -1, -1, 0);
if (fd == -1)
err(1, "cannot open event");
hdr = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
if (hdr == MAP_FAILED)
err(1, "cannot mmap page");
signal(SIGALRM, sig_handler);
ioctl(fd, PERF_COUNTER_IOC_ENABLE, 0);
alarm(10);
for(;quit == 0;) {
uint64_t offset = 0;
unsigned long loop;
/* generate branches */
fib(10);
loop = 0;
do {
loop++;
seq = hdr->lock;
barrier();
if (hdr->index > 0) {
values[0] = rdpmc(hdr->index-1);
offset = hdr->offset;
values[0] += offset;
values[1] = hdr->time_enabled;
values[2] = hdr->time_running;
src = 0;
} else {
ret = read(fd, values, sizeof(values));
src =1;
break;
}
barrier();
} while (hdr->lock != seq);
if (values[2])
values[0]= (uint64_t)((double)values[0] *
values[1]/values[2]);
printf("%20"PRIx64" %s %s offset=0x%"PRIx64" src=%s loop=%lu\n",
values[0],
name,
values[1] != values[2] ? "(scaled)" : "",
offset, src ? "read" : "rdpmc",
loop);
}
ioctl(fd, PERF_COUNTER_IOC_DISABLE, 0);
close(fd);
return 0;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-08-13 11:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-11 22:04 perf_counters issue remapped count stephane eranian
2009-08-13 9:56 ` Ingo Molnar
2009-08-13 11:14 ` stephane eranian
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®