lkml.org 
[lkml]   [2008]   [Dec]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [patch 0/3] [Announcement] Performance Counters for Linux

* Ingo Molnar <mingo@elte.hu> wrote:

> This can be done in a very natural way with our abstraction, and the
> "hello.c" example happens to do exactly that:

multiple people pointed out that we have not posted hello.c :-/

Here's a simple standalone example (full working code attached below):

int main(void)
{
unsigned long long count1, count2;
int fd1, fd2, ret;
fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1);
assert(fd1 >= 0);
fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1);
assert(fd1 >= 0);

for (;;) {
ret = read(fd1, &count1, sizeof(count1));
assert(ret == 8);
ret = read(fd2, &count2, sizeof(count2));
assert(ret == 8);
printf("counter1 value: %Ld instructions\n", count1);
printf("counter2 value: %Ld cachemisses\n", count2);
sleep(1);
}
return 0;
}

which gives this output (one readout per second):

titan:~/perf-counter-test> ./simple
counter1 value: 0 instructions
counter2 value: 0 cachemisses
counter1 value: 23 instructions
counter2 value: 0 cachemisses
counter1 value: 2853 instructions
counter2 value: 6 cachemisses
counter1 value: 5736 instructions
counter2 value: 7 cachemisses
counter1 value: 8619 instructions
counter2 value: 8 cachemisses
counter1 value: 11502 instructions
counter2 value: 8 cachemisses
^C

You need our patchset but then the code below will work just fine. No
libraries, no context setup, nothing - just what is more interesting: the
counter and profiling data.

Ingo

----------------->
/*
* Very simple performance counter testcase.
*/
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <linux/unistd.h>

#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>

#ifdef __x86_64__
# define __NR_perf_counter_open 295
#endif

#ifdef __i386__
# define __NR_perf_counter_open 333
#endif

int
perf_counter_open(int hw_event_type,
unsigned int hw_event_period,
unsigned int record_type,
pid_t pid,
int cpu)
{
return syscall(__NR_perf_counter_open, hw_event_type, hw_event_period,
record_type, pid, cpu);
}
enum hw_event_types {
PERF_COUNT_CYCLES,
PERF_COUNT_INSTRUCTIONS,
PERF_COUNT_CACHE_REFERENCES,
PERF_COUNT_CACHE_MISSES,
PERF_COUNT_BRANCH_INSTRUCTIONS,
PERF_COUNT_BRANCH_MISSES,
};
int main(void)
{
unsigned long long count1, count2;
int fd1, fd2, ret;
fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1);
assert(fd1 >= 0);
fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1);
assert(fd1 >= 0);

for (;;) {
ret = read(fd1, &count1, sizeof(count1));
assert(ret == 8);
ret = read(fd2, &count2, sizeof(count2));
assert(ret == 8);
printf("counter1 value: %Ld instructions\n", count1);
printf("counter2 value: %Ld cachemisses\n", count2);
sleep(1);
}
return 0;
}


\
 
 \ /
  Last update: 2008-12-05 08:07    [from the cache]
©2003-2011 Jasper Spaans